1  /-
  2  Copyright (c) 2017 Johannes Hölzl. All rights reserved.
  3  Released under Apache 2.0 license as described in the file LICENSE.
  4  Authors: Johannes Hölzl
  5  
  6  Type of functions with finite support.
  7  
  8  Functions with finite support provide the basis for the following concrete instances:
  9  
 10   * ℕ →₀ α: Polynomials (where α is a ring)
 11   * (σ →₀ ℕ) →₀ α: Multivariate Polynomials (again α is a ring, and σ are variable names)
 12   * α →₀ ℕ: Multisets
 13   * α →₀ ℤ: Abelian groups freely generated by α
 14   * β →₀ α: Linear combinations over β where α is the scalar ring
 15  
 16  Most of the theory assumes that the range is a commutative monoid. This gives us the big sum
 17  operator as a powerful way to construct `finsupp` elements.
 18  
 19  A general advice is to not use α →₀ β directly, as the type class setup might not be fitting.
 20  The best is to define a copy and select the instances best suited.
 21  
 22  -/
 23  import data.finset data.set.finite algebra.big_operators algebra.module
src         └─────────┘ └─────────────┘ └───────────────────┘ └────────────┘
 24  
 25  noncomputable theory
 26  open_locale classical
 27  
 28  open finset
 29  
 30  variables {α : Type*} {β : Type*} {γ : Type*} {δ : Type*} {ι : Type*}
 31    {α₁ : Type*} {α₂ : Type*} {β₁ : Type*} {β₂ : Type*}
 32  
 33  /-- `finsupp α β`, denoted `α →₀ β`, is the type of functions `f : α → β` such that
 34    `f x = 0` for all but finitely many `x`. -/
 35  structure finsupp (α : Type*) (β : Type*) [has_zero β] :=
id                          └───┘       └───┘   └──────┘ 
src                                             └──────┘
typ                         └───┘       └───┘   └──────┘ 
 36  (support            : finset α)
id                         └────┘ 
src                        └────┘
typ                        └────┘ 
doc                        └────┘
 37  (to_fun             : α → β)
id                           
typ                          
 38  (mem_support_to_fun : ∀a, a ∈ support ↔ to_fun a ≠ 0)
id                              └─────┘  └────┘  
src                                                 
typ                             └─────┘  └────┘  
 39  
 40  infixr ` →₀ `:25 := finsupp
id                       └─────┘
src                      └─────┘
typ                      └─────┘
doc                      └─────┘
 41  
 42  namespace finsupp
 43  
 44  section basic
 45  variable [has_zero β]
id             └──────┘
src            └──────┘
typ            └──────┘
 46  
 47  instance : has_coe_to_fun (α →₀ β) := ⟨λ_, α → β, finsupp.to_fun⟩
id              └────────────┘   └┘               └────────────┘
src             └────────────┘    └┘                   └────────────┘
typ             └────────────┘   └┘               └────────────┘
doc                               └┘
 48  
 49  instance : has_zero (α →₀ β) := ⟨⟨∅, (λ_, 0), λ _, ⟨false.elim, λ H, H rfl⟩⟩⟩
id              └──────┘   └┘                       └────────┘       └─┘
src             └──────┘    └┘                          └────────┘         └─┘
typ             └──────┘   └┘                       └────────┘       └─┘
doc                         └┘
 50  
 51  @[simp] lemma zero_apply {a : α} : (0 : α →₀ β) a = 0 := rfl
id                                           └┘          └─┘
src                                            └┘            └─┘
typ                                          └┘          └─┘
doc    └──┘                                    └┘
 52  
 53  @[simp] lemma support_zero : (0 : α →₀ β).support = ∅ := rfl
id                                      └┘  └─────┘       └─┘
src                                      └┘   └─────┘       └─┘
typ                                     └┘  └─────┘       └─┘
doc    └──┘                              └┘
 54  
 55  instance : inhabited (α →₀ β) := ⟨0⟩
id              └───────┘   └┘ 
src             └───────┘    └┘
typ             └───────┘   └┘ 
doc                          └┘
 56  
 57  @[simp] lemma mem_support_iff {f : α →₀ β} : ∀{a:α}, a ∈ f.support ↔ f a ≠ 0 :=
id                                       └┘              └──────┘    
src                                       └┘                  └──────┘      
typ                                      └┘              └──────┘    
doc    └──┘                               └┘
 58  f.mem_support_to_fun
id   └─────────────────┘
src   └─────────────────┘
typ  └─────────────────┘
 59  
 60  lemma not_mem_support_iff {f : α →₀ β} {a} : a ∉ f.support ↔ f a = 0 :=
id                                   └┘           └──────┘    
src                                   └┘              └──────┘      
typ                                  └┘           └──────┘    
doc                                   └┘
 61  not_iff_comm.1 mem_support_iff.symm
id   └──────────┘  └─────────────┘└───┘
src  └──────────┘  └─────────────┘└───┘
typ  └──────────┘  └─────────────┘└───┘
 62  
 63  @[ext]
doc    └─┘
 64  lemma ext : ∀{f g : α →₀ β}, (∀a, f a = g a) → f = g
id                       └┘                  
src                        └┘                        
typ                      └┘                  
doc                        └┘
 65  | ⟨s, f, hf⟩ ⟨t, g, hg⟩ h :=
 66    begin
st     └─────
 67      have : f = g, { funext a, exact h a },
id                                     
src      └─────┘      └──────┘  └────┘  
typ      └─────┘    └──────┘  └────┘
doc      └─────┘       └──────┘  └────┘  
txt      └─────┘       └──────┘  └────┘  
par      └─────┘       └──────┘  └────┘  
pid      └───┘└┘             └┘         
st   ───────────────┘└──┘└──────┘└──────────┘└┘
 68      subst this,
id             └──┘
src      └────┘
typ      └────┘└──┘
doc      └────┘
txt      └────┘
par      └────┘
pid           
st   ─────────────┘└─
 69      have : s = t, { ext a, exact (hf a).trans (hg a).symm },
id                                   └┘           └┘ 
src      └─────┘       └───┘  └────┘    └──────┘    └─────┘
typ      └─────┘     └───┘  └────┘ └┘ └──────┘ └┘└─────┘
doc      └─────┘       └───┘  └────┘    └──────┘    └─────┘
txt      └─────┘       └───┘  └────┘    └──────┘    └─────┘
par      └─────┘       └───┘  └────┘    └──────┘    └─────┘
pid      └───┘└┘          └┘           └──────┘    └───┘└┘
st   ───────────────┘└──┘└───┘└───────────────────────────────┘└┘
 70      subst this
id             └──┘
src      └────┘    
typ      └────┘└──┘
doc      └────┘    
txt      └────┘    
par      └────┘    
pid               
st   ───────────────
 71    end
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘└─┘
 72  
 73  lemma ext_iff {f g : α →₀ β} : f = g ↔ (∀a:α, f a = g a) :=
id                         └┘                   
src                         └┘                       
typ                        └┘                   
doc                         └┘
 74  ⟨by rintros rfl a; refl, ext⟩
id                            └─┘
src      └───────────┘  └──┘  └─┘
typ      └───────────┘  └──┘  └─┘
doc      └───────────┘  └──┘
txt      └───────────┘  └──┘
par      └───────────┘  └──┘
pid             └────┘
st      └──────────────────┘
 75  
 76  @[simp] lemma support_eq_empty {f : α →₀ β} : f.support = ∅ ↔ f = 0 :=
id                                        └┘     └──────┘     
src                                        └┘       └──────┘      
typ                                       └┘     └──────┘     
doc    └──┘                                └┘
 77  ⟨assume h, ext $ assume a, by_contradiction $ λ H, (finset.ext.1 h a).1 $
id             └─┘            └──────────────┘        └────────┘    
src             └─┘             └──────────────┘         └────────┘      
typ            └─┘            └──────────────┘        └────────┘    
 78    mem_support_iff.2 H, by rintro rfl; refl⟩
id     └─────────────┘  
src    └─────────────┘        └────────┘  └──┘
typ    └─────────────┘       └────────┘  └──┘
doc                            └────────┘  └──┘
txt                            └────────┘  └──┘
par                            └────────┘  └──┘
pid                                  └──┘
st                            └───────────────┘
 79  
 80  instance finsupp.decidable_eq [decidable_eq α] [decidable_eq β] : decidable_eq (α →₀ β) :=
id                                  └──────────┘    └──────────┘     └──────────┘   └┘ 
src                                 └──────────┘     └──────────┘      └──────────┘    └┘
typ                                 └──────────┘    └──────────┘     └──────────┘   └┘ 
doc                                                                                    └┘
 81  assume f g, decidable_of_iff (f.support = g.support ∧ (∀a∈f.support, f a = g a))
id             └──────────────┘  └──────┘  └──────┘     └──────┘      
src              └──────────────┘   └──────┘   └──────┘      └──────┘      
typ            └──────────────┘  └──────┘  └──────┘     └──────┘      
 82    ⟨assume ⟨h₁, h₂⟩, ext $ assume a,
id                 └┘   └─┘          
src                      └─┘
typ                └┘   └─┘          
 83        if h : a ∈ f.support then h₂ a h else
id         └┘       └──────┘          
src        └┘         └──────┘
typ        └┘       └──────┘          
 84          have hf : f a = 0, by rwa [mem_support_iff, not_not] at h,
id           └──┘                    └─────────────┘  └─────┘
src          └──┘                 └───┘└─────────────┘└┘└─────┘└────┘
typ          └──┘               └───┘└─────────────┘└┘└─────┘└────┘
doc                                └───┘               └┘       └────┘
txt                                └───┘               └┘       └────┘
par                                └───┘               └┘       └────┘
pid                                   └┘               └┘       └───┘
st                                └───────────────────┘└───────┘└───┘
 85          have hg : g a = 0, by rwa [h₁, mem_support_iff, not_not] at h,
id                                   └┘  └─────────────┘  └─────┘
src                               └───┘  └┘└─────────────┘└┘└─────┘└────┘
typ                             └───┘└┘└┘└─────────────┘└┘└─────┘└────┘
doc                                └───┘  └┘               └┘       └────┘
txt                                └───┘  └┘               └┘       └────┘
par                                └───┘  └┘               └┘       └────┘
pid                                   └┘  └┘               └┘       └───┘
st                                └──────┘└───────────────┘└───────┘└───┘
 86          by rw [hf, hg],
id                  └┘  └┘
src             └──┘  └┘  
typ             └──┘└┘└┘└┘
doc             └──┘  └┘  
txt             └──┘  └┘  
par             └──┘  └┘  
pid               └┘  └┘  
st             └─────┘└──┘
 87      by rintro rfl; exact ⟨rfl, λ _ _, rfl⟩⟩
id                                         └─┘
src         └────────┘  └────┘    └┘ └────┘└─┘
typ         └────────┘  └────┘    └┘ └────┘└─┘
doc         └────────┘  └────┘    └┘ └────┘   
txt         └────────┘  └────┘    └┘ └────┘   
par         └────────┘  └────┘    └┘ └────┘   
pid               └──┘           └┘ └────┘   
st         └──────────────────────────────────┘
 88  
 89  lemma finite_supp (f : α →₀ β) : set.finite {a | f a ≠ 0} :=
id                           └┘     └────────┘      
src                           └┘      └────────┘         
typ                          └┘     └────────┘      
doc                           └┘      └────────┘
 90  ⟨fintype.of_finset f.support (λ _, mem_support_iff)⟩
id    └───────────────┘ └──────┘      └─────────────┘
src   └───────────────┘  └──────┘       └─────────────┘
typ   └───────────────┘ └──────┘      └─────────────┘
doc   └───────────────┘
 91  
 92  lemma support_subset_iff {s : set α} {f : α →₀ β} :
id                                 └─┘         └┘ 
src                                └─┘           └┘
typ                                └─┘         └┘ 
doc                                              └┘
 93    ↑f.support ⊆ s ↔ (∀a∉s, f a = 0) :=
id     └──────┘           
src     └──────┘               
typ    └──────┘           
 94  by simp only [set.subset_def, mem_coe, mem_support_iff];
id                 └────────────┘  └─────┘  └─────────────┘
src     └─────────┘└────────────┘└┘└─────┘└┘└─────────────┘
typ     └─────────┘└────────────┘└┘└─────┘└┘└─────────────┘
doc     └─────────┘              └┘       └┘               
txt     └─────────┘              └┘       └┘               
par     └─────────┘              └┘       └┘               
pid         └──┘└┘              └┘       └┘               
st     └──────────────────────────────────────────────────────
 95     exact forall_congr (assume a, @not_imp_comm _ _ (classical.dec _) (classical.dec _))
id            └──────────┘             └──────────┘                        └───────────┘
src     └────┘└──────────┘       └──┘ └──────────┘└───┘              └──┘ └───────────┘└────
typ     └────┘└──────────┘       └──┘ └──────────┘└───┘              └──┘ └───────────┘└────
doc     └────┘                   └──┘             └───┘              └──┘              └────
txt     └────┘                   └──┘             └───┘              └──┘              └────
par     └────┘                   └──┘             └───┘              └──┘              └────
pid                             └──┘             └───┘              └──┘              └──┘
st   ────────────────────────────────────────────────────────────────────────────────────────
 96  
src  
typ  
doc  
txt  
par  
pid  
st   
 97  def equiv_fun_on_fintype [fintype α] : (α →₀ β) ≃ (α → β) :=
id                             └─────┘       └┘        
src                            └─────┘         └┘    
typ                            └─────┘       └┘        
doc                            └─────┘         └┘    
 98  ⟨λf a, f a, λf, mk (finset.univ.filter $ λa, f a ≠ 0) f (by simp),
id              └┘  └─────────┘└─────┘            
src                  └┘  └─────────┘└─────┘                     └──┘
typ             └┘  └─────────┘└─────┘                 └──┘
doc                      └─────────┘└─────┘                      └──┘
txt                                                              └──┘
par                                                              └──┘
st                                                              └───┘
 99    begin intro f, ext a, refl end,
src          └─────┘  └───┘  └───┘
typ          └─────┘  └───┘  └───┘
doc          └─────┘  └───┘  └───┘
txt          └─────┘  └───┘  └───┘
par          └─────┘  └───┘  └───┘
pid               └┘     └┘      
st     └───────────┘└─────┘└─────┘└─┘
100    begin intro f, ext a, refl end⟩
src          └─────┘  └───┘  └───┘
typ          └─────┘  └───┘  └───┘
doc          └─────┘  └───┘  └───┘
txt          └─────┘  └───┘  └───┘
par          └─────┘  └───┘  └───┘
pid               └┘     └┘      
st     └───────────┘└─────┘└─────┘└─┘
101  
102  end basic
103  
104  section single
105  variables [has_zero β] {a a' : α} {b : β}
id              └──────┘
src             └──────┘
typ             └──────┘
106  
107  /-- `single a b` is the finitely supported function which has
108    value `b` at `a` and zero otherwise. -/
109  def single (a : α) (b : β) : α →₀ β :=
id                               └┘ 
src                                 └┘
typ                              └┘ 
doc                                 └┘
110  ⟨if b = 0 then ∅ else finset.singleton a, λ a', if a = a' then b else 0, λ a', begin
id                      └──────────────┘     └┘       └┘                 └┘
src                      └──────────────┘               
typ                     └──────────────┘     └┘       └┘                 └┘
doc                        └──────────────┘
st                                                                                  └─────
111    by_cases hb : b = 0; by_cases a = a';
id                                    └┘
src    └───────┘  └─┘ └┘  └───────┘  
typ    └───────┘  └─┘└┘  └───────┘ └┘
doc    └───────┘  └─┘  └┘  └───────┘  
txt    └───────┘  └─┘  └┘  └───────┘  
par    └───────┘  └─┘  └┘  └───────┘  
pid              └─┘              
st   ────────────────────────────────────────
112      simp only [hb, h, if_pos, if_false, mem_singleton],
id                  └┘    └────┘  └──────┘  └───────────┘
src      └─────────┘  └┘ └┘└────┘└┘└──────┘└┘└───────────┘
typ      └─────────┘└┘└┘└┘└────┘└┘└──────┘└┘└───────────┘
doc      └─────────┘  └┘ └┘      └┘        └┘             
txt      └─────────┘  └┘ └┘      └┘        └┘             
par      └─────────┘  └┘ └┘      └┘        └┘             
pid          └──┘└┘  └┘ └┘      └┘        └┘             
st   ─────────────────────────────────────────────────────┘└─
113    { exact ⟨false.elim, λ H, H rfl⟩ },
id              └────────┘         └─┘
src      └────┘ └────────┘└┘ └──┘ └─┘└┘
typ      └────┘ └────────┘└┘ └──┘ └─┘└┘
doc      └────┘           └┘ └──┘    └┘
txt      └────┘           └┘ └──┘    └┘
par      └────┘           └┘ └──┘    └┘
pid                      └┘ └──┘    
st   ───┘└─────────────────────────────┘└┘
114    { exact ⟨false.elim, λ H, H rfl⟩ },
id              └────────┘         └─┘
src      └────┘ └────────┘└┘ └──┘ └─┘└┘
typ      └────┘ └────────┘└┘ └──┘ └─┘└┘
doc      └────┘           └┘ └──┘    └┘
txt      └────┘           └┘ └──┘    └┘
par      └────┘           └┘ └──┘    └┘
pid                      └┘ └──┘    
st   ───┘└─────────────────────────────┘└┘
115    { exact ⟨λ _, hb, λ _, rfl⟩ },
id                   └┘       └─┘
src      └────┘  └──┘  └┘ └──┘└─┘└┘
typ      └────┘  └──┘└┘└┘ └──┘└─┘└┘
doc      └────┘  └──┘  └┘ └──┘   └┘
txt      └────┘  └──┘  └┘ └──┘   └┘
par      └────┘  └──┘  └┘ └──┘   └┘
pid             └──┘  └┘ └──┘   
st   ───┘└────────────────────────┘└┘
116    { exact ⟨λ H _, h H.symm, λ H, (H rfl).elim⟩ }
id                       └───┘          └─┘
src      └────┘  └────┘  └───┘└┘ └──┘  └─┘└──────┘
typ      └────┘  └────┘ └───┘└┘ └──┘  └─┘└──────┘
doc      └────┘  └────┘       └┘ └──┘     └──────┘
txt      └────┘  └────┘       └┘ └──┘     └──────┘
par      └────┘  └────┘       └┘ └──┘     └──────┘
pid             └────┘       └┘ └──┘     └─────┘
st   ──────────────────────────────────────────────┘└─
117  end⟩
st   ──┘
118  
119  lemma single_apply : (single a b : α →₀ β) a' = if a = a' then b else 0 := rfl
id                         └────┘      └┘   └┘       └┘                 └─┘
src                        └────┘         └┘                                  └─┘
typ                        └────┘      └┘   └┘       └┘                 └─┘
doc                        └────┘         └┘
120  
121  @[simp] lemma single_eq_same : (single a b : α →₀ β) a = b := if_pos rfl
id                                   └────┘      └┘         └────┘ └─┘
src                                  └────┘         └┘            └────┘ └─┘
typ                                  └────┘      └┘         └────┘ └─┘
doc    └──┘                          └────┘         └┘
122  
123  @[simp] lemma single_eq_of_ne (h : a ≠ a') : (single a b : α →₀ β) a' = 0 := if_neg h
id                                        └┘     └────┘      └┘   └┘       └────┘ 
src                                               └────┘         └┘             └────┘
typ                                       └┘     └────┘      └┘   └┘       └────┘ 
doc    └──┘                                        └────┘         └┘
124  
125  @[simp] lemma single_zero : (single a 0 : α →₀ β) = 0 :=
id                                └────┘       └┘   
src                               └────┘         └┘    
typ                               └────┘       └┘   
doc    └──┘                       └────┘         └┘
126  ext $ assume a',
id   └─┘          └┘
src  └─┘
typ  └─┘          └┘
127  begin
st   └─────
128    by_cases h : a = a',
id                    └┘
src    └───────┘ └─┘ 
typ    └───────┘ └─┘└┘
doc    └───────┘ └─┘  
txt    └───────┘ └─┘  
par    └───────┘ └─┘  
pid             └─┘  
st   ────────────────────┘└─
129    { rw [h, single_eq_same, zero_apply] },
id             └────────────┘  └────────┘
src      └──┘ └┘└────────────┘└┘└────────┘└┘
typ      └──┘└┘└────────────┘└┘└────────┘└┘
doc      └──┘ └┘              └┘          └┘
txt      └──┘ └┘              └┘          └┘
par      └──┘ └┘              └┘          └┘
pid        └┘ └┘              └┘          
st   ───┘└───┘└──────────────┘└──────────┘└┘
130    { rw [single_eq_of_ne h, zero_apply] }
id           └─────────────┘   └────────┘
src      └──┘└─────────────┘ └┘└────────┘└┘
typ      └──┘└─────────────┘└┘└────────┘└┘
doc      └──┘                └┘          └┘
txt      └──┘                └┘          └┘
par      └──┘                └┘          └┘
pid        └┘                └┘          
st   ────────────────────────┘└──────────┘└─
131  end
st   ──┘
132  
133  lemma support_single_ne_zero (hb : b ≠ 0) : (single a b).support = {a} :=
id                                              └────┘   └─────┘   
src                                              └────┘     └─────┘   
typ                                             └────┘   └─────┘   
doc                                               └────┘
134  if_neg hb
id   └────┘ └┘
src  └────┘
typ  └────┘ └┘
135  
136  lemma support_single_subset : (single a b).support ⊆ {a} :=
id                                  └────┘   └─────┘   
src                                 └────┘     └─────┘   
typ                                 └────┘   └─────┘   
doc                                 └────┘
137  show ite _ _ _ ⊆ _, by split_ifs; [exact empty_subset _, exact subset.refl _]
id        └─┘                               └──────────┘          └─────────┘
src       └─┘              └───────┘  └────┘└──────────┘└┘  └────┘└─────────┘└┘
typ       └─┘              └───────┘  └────┘└──────────┘└┘  └────┘└─────────┘└┘
doc                         └───────┘   └────┘            └┘  └────┘           └┘
txt                         └───────┘   └────┘            └┘  └────┘           └┘
par                         └───────┘   └────┘            └┘  └────┘           └┘
pid                                                      └┘                  └┘
st                         └─────────────────────────────────────────────────────┘
138  
139  lemma injective_single (a : α) : function.injective (single a : β → α →₀ β) :=
id                                   └────────────────┘  └────┘        └┘ 
src                                   └────────────────┘  └────┘           └┘
typ                                  └────────────────┘  └────┘        └┘ 
doc                                                       └────┘           └┘
140  assume b₁ b₂ eq,
id          └┘ └┘ └┘
src               └┘
typ         └┘ └┘ └┘
141  have (single a b₁ : α →₀ β) a = (single a b₂ : α →₀ β) a, by rw eq,
id         └────┘  └┘    └┘      └────┘  └┘    └┘           └┘
src        └────┘          └┘        └────┘          └┘          └─┘└┘
typ        └────┘  └┘    └┘      └────┘  └┘    └┘        └─┘└┘
doc        └────┘          └┘         └────┘          └┘          └─┘
txt                                                               └─┘
par                                                               └─┘
pid                                                                 
st                                                               └────┘
142  by rwa [single_eq_same, single_eq_same] at this
id           └────────────┘  └────────────┘
src     └───┘└────────────┘└┘└────────────┘└─────────
typ     └───┘└────────────┘└┘└────────────┘└─────────
doc     └───┘              └┘              └─────────
txt     └───┘              └┘              └─────────
par     └───┘              └┘              └─────────
pid        └┘              └┘              └──────┘
st     └──────────────────┘└──────────────┘└────────
143  
src  
typ  
doc  
txt  
par  
pid  
st   
144  lemma single_eq_single_iff (a₁ a₂ : α) (b₁ b₂ : β) :
id                                                  
typ                                                 
145    single a₁ b₁ = single a₂ b₂ ↔ ((a₁ = a₂ ∧ b₁ = b₂) ∨ (b₁ = 0 ∧ b₂ = 0)) :=
id     └────┘ └┘ └┘  └────┘ └┘ └┘    └┘  └┘  └┘  └┘    └┘     └┘ 
src    └────┘        └────┘                                      
typ    └────┘ └┘ └┘  └────┘ └┘ └┘    └┘  └┘  └┘  └┘    └┘     └┘ 
doc    └────┘         └────┘
146  begin
st   └─────
147    split,
src    └───┘
typ    └───┘
doc    └───┘
txt    └───┘
par    └───┘
st   ──────┘└─
148    { assume eq,
src      └───────┘
typ      └───────┘
doc      └───────┘
txt      └───────┘
par      └───────┘
pid      └───────┘
st   ───┘└───────┘└─
149      by_cases a₁ = a₂,
id                └┘  └┘
src      └───────┘  
typ      └───────┘└┘└┘
doc      └───────┘   
txt      └───────┘   
par      └───────┘   
pid                 
st   ───────────────────┘└─
150      { refine or.inl ⟨h, _⟩,
id                └────┘  
src        └─────┘└────┘  └──┘
typ        └─────┘└────┘ └──┘
doc        └─────┘        └──┘
txt        └─────┘        └──┘
par        └─────┘        └──┘
pid                      └──┘
st   ─────┘└──────────────────┘└─
151        rwa [h, (injective_single a₂).eq_iff] at eq },
id                 └──────────────┘ └┘
src        └───┘ └┘ └──────────────┘  └──────────────┘
typ        └───┘└┘ └──────────────┘└┘└──────────────┘
doc        └───┘ └┘                   └──────────────┘
txt        └───┘ └┘                   └──────────────┘
par        └───┘ └┘                   └──────────────┘
pid           └┘ └┘                   └───────┘└────┘
st   ───────────┘└───────────────────────────┘└┘└─────┘└┘
152      { rw [finsupp.ext_iff] at eq,
id             └─────────────┘
src        └──┘└─────────────┘└─────┘
typ        └──┘└─────────────┘└─────┘
doc        └──┘               └─────┘
txt        └──┘               └─────┘
par        └──┘               └─────┘
pid          └┘               └────┘
st   ────────────────────────┘└────┘└─
153        have h₁ := eq a₁,
id                    └┘ └┘
src        └─────────┘└┘
typ        └─────────┘└┘└┘
doc        └─────────┘  
txt        └─────────┘  
par        └─────────┘  
pid        └─────┘└─┘  
st   ─────────────────────┘└─
154        have h₂ := eq a₂,
id                    └┘ └┘
src        └─────────┘└┘
typ        └─────────┘└┘└┘
doc        └─────────┘  
txt        └─────────┘  
par        └─────────┘  
pid        └─────┘└─┘  
st   ─────────────────────┘└─
155        simp only [single_eq_same, single_eq_of_ne h, single_eq_of_ne (ne.symm h)] at h₁ h₂,
id                    └────────────┘  └─────────────┘   └─────────────┘  └─────┘ 
src        └─────────┘└────────────┘└┘└─────────────┘ └┘└─────────────┘ └─────┘ └─────────┘
typ        └─────────┘└────────────┘└┘└─────────────┘└┘└─────────────┘ └─────┘└─────────┘
doc        └─────────┘              └┘                └┘                        └─────────┘
txt        └─────────┘              └┘                └┘                        └─────────┘
par        └─────────┘              └┘                └┘                        └─────────┘
pid            └──┘└┘              └┘                └┘                        └┘└──────┘
st   ────────────────────────────────────────────────────────────────────────────────────────┘└─
156        exact or.inr ⟨h₁, h₂.symm⟩ } },
id               └────┘  └┘  └─────┘
src        └────┘└────┘   └┘└─────┘└┘
typ        └────┘└────┘ └┘└┘└─────┘└┘
doc        └────┘         └┘       └┘
txt        └────┘         └┘       └┘
par        └────┘         └┘       └┘
pid                      └┘       
st   ────────────────────────────────┘└──┘
157    { rintros (⟨rfl, rfl⟩ | ⟨rfl, rfl⟩),
src      └───────────────────────────────┘
typ      └───────────────────────────────┘
doc      └───────────────────────────────┘
txt      └───────────────────────────────┘
par      └───────────────────────────────┘
pid             └────────────────────────┘
st   ────────────────────────────────────┘└─
158      { refl },
src        └───┘
typ        └───┘
doc        └───┘
txt        └───┘
par        └───┘
pid            
st   ─────┘└───┘└┘
159      { rw [single_zero, single_zero] } }
id             └─────────┘  └─────────┘
src        └──┘└─────────┘└┘└─────────┘└┘
typ        └──┘└─────────┘└┘└─────────┘└┘
doc        └──┘           └┘           └┘
txt        └──┘           └┘           └┘
par        └──┘           └┘           └┘
pid          └┘           └┘           
st   ────────────────────┘└───────────┘└───
160  end
st   ──┘
161  
162  lemma single_right_inj (h : b ≠ 0) :
id                                
src                                
typ                               
163    single a b = single a' b ↔ a = a' :=
id     └────┘    └────┘ └┘     └┘
src    └────┘      └────┘         
typ    └────┘    └────┘ └┘     └┘
doc    └────┘       └────┘
164  ⟨λ H, by simpa [h, single_eq_single_iff] using H, λ H, by rw [H]⟩
id                    └──────────────────┘                     
src           └─────┘ └┘└──────────────────┘└──────┘           └──┘ 
typ          └─────┘└┘└──────────────────┘└──────┘         └──┘
doc           └─────┘ └┘                    └──────┘           └──┘ 
txt           └─────┘ └┘                    └──────┘           └──┘ 
par           └─────┘ └┘                    └──────┘           └──┘ 
pid                 └┘                    └────┘             └┘ 
st           └──────────────────────────────────────┘         └────┘
165  
166  lemma single_eq_zero : single a b = 0 ↔ b = 0 :=
id                          └────┘        
src                         └────┘           
typ                         └────┘        
doc                         └────┘
167  ⟨λ h, by { rw ext_iff at h, simpa only [finsupp.single_eq_same, finsupp.zero_apply] using h a },
id                └─────┘                   └────────────────────┘  └────────────────┘         
src             └─┘└─────┘└───┘  └──────────┘└────────────────────┘└┘└────────────────┘└──────┘  
typ            └─┘└─────┘└───┘  └──────────┘└────────────────────┘└┘└────────────────┘└──────┘
doc             └─┘       └───┘  └──────────┘                      └┘                  └──────┘  
txt             └─┘       └───┘  └──────────┘                      └┘                  └──────┘  
par             └─┘       └───┘  └──────────┘                      └┘                  └──────┘  
pid                      └───┘       └──┘└┘                      └┘                  └────┘  
st           └────────────────┘└──────────────────────────────────────────────────────────────────┘└┘
168  λ h, by rw [h, single_zero]⟩
id                └─────────┘
src          └──┘ └┘└─────────┘
typ         └──┘└┘└─────────┘
doc          └──┘ └┘           
txt          └──┘ └┘           
par          └──┘ └┘           
pid            └┘ └┘           
st          └────┘└───────────┘
169  
170  lemma single_swap {α β : Type*} [has_zero β] (a₁ a₂ : α) (b : β) :
id                                    └──────┘                   
src                                   └──────┘
typ                                   └──────┘                   
171    (single a₁ b : α → β) a₂ = (single a₂ b : α → β) a₁ :=
id      └────┘ └┘         └┘   └────┘ └┘         └┘
src     └────┘                    └────┘
typ     └────┘ └┘         └┘   └────┘ └┘         └┘
doc     └────┘                     └────┘
172  by simp [single_apply]; ac_refl
id            └──────────┘
src     └────┘└──────────┘  └───────
typ     └────┘└──────────┘  └───────
doc     └────┘              └───────
txt     └────┘              └───────
par     └────┘              └───────
pid                              
st     └─────────────────────────────
173  
src  
typ  
doc  
txt  
par  
pid  
st   
174  lemma unique_single [unique α] (x : α →₀ β) : x = single (default α) (x (default α)) :=
id                        └────┘         └┘       └────┘  └─────┘      └─────┘ 
src                       └────┘           └┘         └────┘  └─────┘        └─────┘
typ                       └────┘         └┘       └────┘  └─────┘      └─────┘ 
doc                                        └┘          └────┘
175  by ext i; simp [unique.eq_default i]
id                   └───────────────┘ 
src     └───┘  └────┘└───────────────┘ └─
typ     └───┘  └────┘└───────────────┘└─
doc     └───┘  └────┘                  └─
txt     └───┘  └────┘                  └─
par     └───┘  └────┘                  └─
pid        └┘                        
st     └──────────────────────────────────
176  
src  
typ  
doc  
txt  
par  
pid  
st   
177  @[simp] lemma unique_single_eq_iff [unique α] {b' : β} :
id                                       └────┘         
src                                      └────┘
typ                                      └────┘         
doc    └──┘
178    single a b = single a' b' ↔ b = b' :=
id     └────┘    └────┘ └┘ └┘    └┘
src    └────┘      └────┘          
typ    └────┘    └────┘ └┘ └┘    └┘
doc    └────┘       └────┘
179  begin
st   └─────
180    rw [single_eq_single_iff],
id         └──────────────────┘
src    └──┘└──────────────────┘
typ    └──┘└──────────────────┘
doc    └──┘                    
txt    └──┘                    
par    └──┘                    
pid      └┘                    
st   ─────────────────────────┘└──
181    split,
src    └───┘
typ    └───┘
doc    └───┘
txt    └───┘
par    └───┘
st   ──────┘└─
182    { rintros (⟨_, rfl⟩ | ⟨rfl, rfl⟩); refl },
src      └─────────────────────────────┘  └───┘
typ      └─────────────────────────────┘  └───┘
doc      └─────────────────────────────┘  └───┘
txt      └─────────────────────────────┘  └───┘
par      └─────────────────────────────┘  └───┘
pid             └──────────────────────┘      
st   ───┘└────────────────────────────────────┘└┘
183    { intro h, left, exact ⟨subsingleton.elim _ _, h⟩ }
id                             └───────────────┘      
src      └─────┘  └──┘  └────┘ └───────────────┘└────┘ └┘
typ      └─────┘  └──┘  └────┘ └───────────────┘└────┘└┘
doc      └─────┘  └──┘  └────┘                  └────┘ └┘
txt      └─────┘  └──┘  └────┘                  └────┘ └┘
par      └─────┘  └──┘  └────┘                  └────┘ └┘
pid           └┘                               └────┘ 
st   ──────────┘└────┘└─────────────────────────────────┘└─
184  end
st   ──┘
185  
186  end single
187  
188  section on_finset
189  variables [has_zero β]
id              └──────┘
src             └──────┘
typ             └──────┘
190  
191  /-- `on_finset s f hf` is the finsupp function representing `f` restricted to the set `s`.
192  The function needs to be 0 outside of `s`. Use this when the set needs filtered anyway, otherwise
193  often better set representation is available. -/
194  def on_finset (s : finset α) (f : α → β) (hf : ∀a, f a ≠ 0 → a ∈ s) : α →₀ β :=
id                      └────┘                                    └┘ 
src                     └────┘                                             └┘
typ                     └────┘                                    └┘ 
doc                     └────┘                                               └┘
195  ⟨s.filter (λa, f a ≠ 0), f,
id    └─────┘            
src    └─────┘          
typ   └─────┘            
doc    └─────┘
196    assume a, classical.by_cases
id              └────────────────┘
src              └────────────────┘
typ             └────────────────┘
197      (assume h : f a = 0, by rw mem_filter; exact ⟨and.right, λ H, (H h).elim⟩)
id                               └────────┘         └───────┘          
src                             └─┘└────────┘  └────┘ └───────┘└┘ └──┘   └─────┘
typ                           └─┘└────────┘  └────┘ └───────┘└┘ └──┘  └─────┘
doc                              └─┘            └────┘          └┘ └──┘   └─────┘
txt                              └─┘            └────┘          └┘ └──┘   └─────┘
par                              └─┘            └────┘          └┘ └──┘   └─────┘
pid                                                           └┘ └──┘   └─────┘
st                              └────────────────────────────────────────────────┘
198      (assume h : f a ≠ 0, by rw mem_filter; simp only [iff_true_intro h, hf a h, true_and])⟩
id                               └────────┘             └────────────┘   └┘    └──────┘
src                             └─┘└────────┘  └─────────┘└────────────┘ └┘    └┘└──────┘
typ                           └─┘└────────┘  └─────────┘└────────────┘└┘└┘└┘└──────┘
doc                              └─┘            └─────────┘               └┘    └┘        
txt                              └─┘            └─────────┘               └┘    └┘        
par                              └─┘            └─────────┘               └┘    └┘        
pid                                                └──┘└┘               └┘    └┘        
st                              └────────────────────────────────────────────────────────────┘
199  
200  @[simp] lemma on_finset_apply {s : finset α} {f : α → β} {hf a} :
id                                      └────┘           
src                                     └────┘
typ                                     └────┘           
doc    └──┘                             └────┘
201    (on_finset s f hf : α →₀ β) a = f a :=
id      └───────┘   └┘    └┘      
src     └───────┘            └┘      
typ     └───────┘   └┘    └┘      
doc     └───────┘            └┘
202  rfl
id   └─┘
src  └─┘
typ  └─┘
203  
204  @[simp] lemma support_on_finset_subset {s : finset α} {f : α → β} {hf} :
id                                               └────┘           
src                                              └────┘
typ                                              └────┘           
doc    └──┘                                      └────┘
205    (on_finset s f hf).support ⊆ s := filter_subset _
id      └───────┘   └┘ └─────┘       └───────────┘
src     └───────┘        └─────┘        └───────────┘
typ     └───────┘   └┘ └─────┘       └───────────┘
doc     └───────┘
206  
207  end on_finset
208  
209  section map_range
210  variables [has_zero β₁] [has_zero β₂]
id              └──────┘      └──────┘
src             └──────┘      └──────┘
typ             └──────┘      └──────┘
211  
212  /-- The composition of `f : β₁ → β₂` and `g : α →₀ β₁` is
213    `map_range f hf g : α →₀ β₂`, well defined when `f 0 = 0`. -/
214  def map_range (f : β₁ → β₂) (hf : f 0 = 0) (g : α →₀ β₁) : α →₀ β₂ :=
id                      └┘   └┘                     └┘ └┘     └┘ └┘
src                                                   └┘         └┘
typ                     └┘   └┘                     └┘ └┘     └┘ └┘
doc                                                    └┘         └┘
215  on_finset g.support (f ∘ g) $
id   └───────┘ └──────┘    
src  └───────┘  └──────┘    
typ  └───────┘ └──────┘    
doc  └───────┘
216    assume a, by rw [mem_support_iff, not_imp_not]; exact λ H, (congr_arg f H).trans hf
id                     └─────────────┘  └─────────┘               └───────┘           └┘
src                 └──┘└─────────────┘└┘└─────────┘  └────┘ └──┘ └───────┘  └──────┘  
typ                └──┘└─────────────┘└┘└─────────┘  └────┘ └──┘ └───────┘ └──────┘└┘
doc                 └──┘               └┘             └────┘ └──┘            └──────┘  
txt                 └──┘               └┘             └────┘ └──┘            └──────┘  
par                 └──┘               └┘             └────┘ └──┘            └──────┘  
pid                   └┘               └┘                   └──┘            └──────┘  
st                 └──────────────────┘└───────────┘└─────────────────────────────────────
217  
src  
typ  
doc  
txt  
par  
pid  
st   
218  @[simp] lemma map_range_apply {f : β₁ → β₂} {hf : f 0 = 0} {g : α →₀ β₁} {a : α} :
id                                      └┘   └┘                     └┘ └┘       
src                                                                   └┘
typ                                     └┘   └┘                     └┘ └┘       
doc    └──┘                                                            └┘
219    map_range f hf g a = f (g a) :=
id     └───────┘  └┘       
src    └───────┘          
typ    └───────┘  └┘       
doc    └───────┘
220  rfl
id   └─┘
src  └─┘
typ  └─┘
221  
222  @[simp] lemma map_range_zero {f : β₁ → β₂} {hf : f 0 = 0} : map_range f hf (0 : α →₀ β₁) = 0 :=
id                                     └┘   └┘                 └───────┘  └┘       └┘ └┘  
src                                                             └───────┘             └┘     
typ                                    └┘   └┘                 └───────┘  └┘       └┘ └┘  
doc    └──┘                                                      └───────┘             └┘
223  finsupp.ext $ λ a, by simp [hf]
id   └─────────┘                └┘
src  └─────────┘           └────┘  └─
typ  └─────────┘          └────┘└┘└─
doc                        └────┘  └─
txt                        └────┘  └─
par                        └────┘  └─
pid                              
st                        └──────────
224  
src  
typ  
doc  
txt  
par  
pid  
st   
225  lemma support_map_range {f : β₁ → β₂} {hf : f 0 = 0} {g : α →₀ β₁} :
id                                └┘   └┘                     └┘ └┘
src                                                             └┘
typ                               └┘   └┘                     └┘ └┘
doc                                                              └┘
226    (map_range f hf g).support ⊆ g.support :=
id      └───────┘  └┘  └─────┘   └──────┘
src     └───────┘        └─────┘    └──────┘
typ     └───────┘  └┘  └─────┘   └──────┘
doc     └───────┘
227  support_on_finset_subset
id   └──────────────────────┘
src  └──────────────────────┘
typ  └──────────────────────┘
228  
229  @[simp] lemma map_range_single {f : β₁ → β₂} {hf : f 0 = 0} {a : α} {b : β₁} :
id                                       └┘   └┘                           └┘
src                                                         
typ                                      └┘   └┘                           └┘
doc    └──┘
230    map_range f hf (single a b) = single a (f b) :=
id     └───────┘  └┘  └────┘     └────┘    
src    └───────┘       └────┘       └────┘
typ    └───────┘  └┘  └────┘     └────┘    
doc    └───────┘       └────┘        └────┘
231  finsupp.ext $ λ a', show f (ite _ _ _) = ite _ _ _, by split_ifs; [refl, exact hf]
id   └─────────┘     └┘         └─┘         └─┘                                  └┘
src  └─────────┘                 └─┘         └─┘           └───────┘  └──┘  └────┘
typ  └─────────┘     └┘         └─┘         └─┘           └───────┘  └──┘  └────┘└┘
doc                                                         └───────┘   └──┘  └────┘
txt                                                         └───────┘   └──┘  └────┘
par                                                         └───────┘   └──┘  └────┘
pid                                                                                
st                                                         └──────────────────────────┘
232  
233  end map_range
234  
235  section emb_domain
236  variables [has_zero β]
id              └──────┘
src             └──────┘
typ             └──────┘
237  
238  /-- Given `f : α₁ ↪ α₂` and `v : α₁ →₀ β`, `emb_domain f v : α₂ →₀ β` is the finitely supported
239  function whose value at `f a : α₂` is `v a`. For a `b : α₂` outside the range of `f` it is zero. -/
240  def emb_domain (f : α₁ ↪ α₂) (v : α₁ →₀ β) : α₂ →₀ β :=
id                       └┘  └┘       └┘ └┘     └┘ └┘ 
src                                      └┘         └┘
typ                      └┘  └┘       └┘ └┘     └┘ └┘ 
doc                                       └┘         └┘
241  begin
st   └─────
242    refine ⟨v.support.map f, λa₂,
src    └─────┘               └┘ └───
typ    └─────┘               └┘ └───
doc    └─────┘               └┘ └───
txt    └─────┘               └┘ └───
par    └─────┘               └┘ └───
pid                         └┘ └───
st   ────────────────────────────────
243      if h : a₂ ∈ v.support.map f then v (v.support.choose (λa₁, f a₁ = a₂) _) else 0, _⟩,
id       └┘         └───────────┘           └──────────────┘           
src  ───┘└┘└───┘  └───────────┘ └────┘  └──────────────┘  └──┘     └─────────────┘
typ  ───┘└┘└───┘  └───────────┘ └────┘  └──────────────┘  └──┘    └─────────────┘
doc  ───┘  └───┘                 └────┘                    └──┘      └─────────────┘
txt  ───┘  └───┘                 └────┘                    └──┘      └─────────────┘
par  ───┘  └───┘                 └────┘                    └──┘      └─────────────┘
pid  ───┘  └───┘                 └────┘                    └──┘      └─────────────┘
st   ──────────────────────────────────────────────────────────────────────────────────────┘└─
244    { rcases finset.mem_map.1 h with ⟨a, ha, rfl⟩,
id              └────────────┘   
src      └─────┘└────────────┘└─┘ └────────────────┘
typ      └─────┘└────────────┘└─┘└────────────────┘
doc      └─────┘              └─┘ └────────────────┘
txt      └─────┘              └─┘ └────────────────┘
par      └─────┘              └─┘ └────────────────┘
pid                          └─┘ └────────────────┘
st   ───┘└─────────────────────────────────────────┘└─
245      exact exists_unique.intro a ⟨ha, rfl⟩ (assume b ⟨_, hb⟩, f.inj hb) },
id             └─────────────────┘   └┘  └─┘                └┘   └───┘
src      └────┘└─────────────────┘    └┘└─┘└┘       └─────┘  └─┘└───┘  └┘
typ      └────┘└─────────────────┘ └┘└┘└─┘└┘       └─────┘└┘└─┘└───┘  └┘
doc      └────┘                       └┘   └┘       └─────┘  └─┘       └┘
txt      └────┘                       └┘   └┘       └─────┘  └─┘       └┘
par      └────┘                       └┘   └┘       └─────┘  └─┘       └┘
pid                                  └┘   └┘       └─────┘  └─┘       
st   ──────────────────────────────────────────────────────────────────────┘└┘
246    { assume a₂,
src      └───────┘
typ      └───────┘
doc      └───────┘
txt      └───────┘
par      └───────┘
pid      └───────┘
st   ────────────┘└─
247      split_ifs,
src      └───────┘
typ      └───────┘
doc      └───────┘
txt      └───────┘
par      └───────┘
st   ────────────┘└─
248      { simp [h],
id               
src        └────┘ 
typ        └────┘
doc        └────┘ 
txt        └────┘ 
par        └────┘ 
pid             
st   ─────┘└──────┘└─
249        rw [← finsupp.not_mem_support_iff, not_not],
id               └─────────────────────────┘  └─────┘
src        └────┘└─────────────────────────┘└┘└─────┘
typ        └────┘└─────────────────────────┘└┘└─────┘
doc        └────┘                           └┘       
txt        └────┘                           └┘       
par        └────┘                           └┘       
pid          └──┘                           └┘       
st   ──────────────────────────────────────┘└───────┘└──
250        apply finset.choose_mem },
id               └───────────────┘
src        └────┘└───────────────┘
typ        └────┘└───────────────┘
doc        └────┘                 
txt        └────┘                 
par        └────┘                 
pid                              
st   ─────────────────────────────┘└┘
251      { simp [h] } }
id               
src        └────┘ └┘
typ        └────┘└┘
doc        └────┘ └┘
txt        └────┘ └┘
par        └────┘ └┘
pid             
st   ──────────────┘└───
252  end
st   ──┘
253  
254  lemma support_emb_domain (f : α₁ ↪ α₂) (v : α₁ →₀ β) :
id                                 └┘  └┘       └┘ └┘ 
src                                                └┘
typ                                └┘  └┘       └┘ └┘ 
doc                                                 └┘
255    (emb_domain f v).support = v.support.map f :=
id      └────────┘   └─────┘   └──────┘└──┘ 
src     └────────┘     └─────┘    └──────┘└──┘
typ     └────────┘   └─────┘   └──────┘└──┘ 
doc     └────────┘
256  rfl
id   └─┘
src  └─┘
typ  └─┘
257  
258  lemma emb_domain_zero (f : α₁ ↪ α₂) : (emb_domain f 0 : α₂ →₀ β) = 0 :=
id                              └┘  └┘     └────────┘      └┘ └┘   
src                                        └────────┘          └┘    
typ                             └┘  └┘     └────────┘      └┘ └┘   
doc                                         └────────┘          └┘
259  rfl
id   └─┘
src  └─┘
typ  └─┘
260  
261  lemma emb_domain_apply (f : α₁ ↪ α₂) (v : α₁ →₀ β) (a : α₁) :
id                               └┘  └┘       └┘ └┘        └┘
src                                              └┘
typ                              └┘  └┘       └┘ └┘        └┘
doc                                               └┘
262    emb_domain f v (f a) = v a :=
id     └────────┘         
src    └────────┘           
typ    └────────┘         
doc    └────────┘
263  begin
st   └─────
264    change dite _ _ _ = _,
id            └──┘       
src    └─────┘└──┘└─────┘└┘
typ    └─────┘└──┘└─────┘└┘
doc    └─────┘    └─────┘ └┘
txt    └─────┘    └─────┘ └┘
par    └─────┘    └─────┘ └┘
pid              └─────┘ └┘
st   ──────────────────────┘└─
265    split_ifs; rw [finset.mem_map' f] at h,
id                    └─────────────┘ 
src    └───────┘  └──┘└─────────────┘ └────┘
typ    └───────┘  └──┘└─────────────┘└────┘
doc    └───────┘  └──┘                └────┘
txt    └───────┘  └──┘                └────┘
par    └───────┘  └──┘                └────┘
pid                 └┘                └───┘
st   ────────────────┘└───────────────┘└───┘└─
266    { refine congr_arg (v : α₁ → β) (f.inj' _),
id              └───────┘     └┘      └────┘
src      └─────┘└───────┘  └─┘    └┘ └────┘└─┘
typ      └─────┘└───────┘ └─┘└┘ └┘ └────┘└─┘
doc      └─────┘           └─┘    └┘       └─┘
txt      └─────┘           └─┘    └┘       └─┘
par      └─────┘           └─┘    └┘       └─┘
pid                       └─┘    └┘       └─┘
st   ───┘└──────────────────────────────────────┘└─
267      exact finset.choose_property (λa₁, f a₁ = f a) _ _ },
id             └────────────────────┘               
src      └────┘└────────────────────┘  └──┘      └────┘
typ      └────┘└────────────────────┘  └──┘    └────┘
doc      └────┘                        └──┘      └────┘
txt      └────┘                        └──┘      └────┘
par      └────┘                        └──┘      └────┘
pid                                   └──┘      └───┘
st   ──────────────────────────────────────────────────────┘└┘
268    { exact (finsupp.not_mem_support_iff.1 h).symm }
id              └─────────────────────────┘   
src      └────┘ └─────────────────────────┘└─┘ └─────┘
typ      └────┘ └─────────────────────────┘└─┘└─────┘
doc      └────┘                            └─┘ └─────┘
txt      └────┘                            └─┘ └─────┘
par      └────┘                            └─┘ └─────┘
pid                                       └─┘ └───┘└┘
st   ────────────────────────────────────────────────┘└─
269  end
st   ──┘
270  
271  lemma emb_domain_notin_range (f : α₁ ↪ α₂) (v : α₁ →₀ β) (a : α₂) (h : a ∉ set.range f) :
id                                     └┘  └┘       └┘ └┘        └┘         └───────┘ 
src                                                    └┘                     └───────┘
typ                                    └┘  └┘       └┘ └┘        └┘         └───────┘ 
doc                                                     └┘                      └───────┘
272    emb_domain f v a = 0 :=
id     └────────┘    
src    └────────┘       
typ    └────────┘    
doc    └────────┘
273  begin
st   └─────
274    refine dif_neg (mt (assume h, _) h),
id            └─────┘  └┘               
src    └─────┘└─────┘ └┘       └─────┘ 
typ    └─────┘└─────┘ └┘       └─────┘
doc    └─────┘                 └─────┘ 
txt    └─────┘                 └─────┘ 
par    └─────┘                 └─────┘ 
pid                           └─────┘ 
st   ────────────────────────────────────┘└─
275    rcases finset.mem_map.1 h with ⟨a, h, rfl⟩,
id            └────────────┘   
src    └─────┘└────────────┘└─┘ └───────────────┘
typ    └─────┘└────────────┘└─┘└───────────────┘
doc    └─────┘              └─┘ └───────────────┘
txt    └─────┘              └─┘ └───────────────┘
par    └─────┘              └─┘ └───────────────┘
pid                        └─┘ └───────────────┘
st   ───────────────────────────────────────────┘└─
276    exact set.mem_range_self a
id           └────────────────┘ 
src    └────┘└────────────────┘ 
typ    └────┘└────────────────┘
doc    └────┘                   
txt    └────┘                   
par    └────┘                   
pid                            
st   ────────────────────────────┘
277  end
st   └─┘
278  
279  lemma emb_domain_inj {f : α₁ ↪ α₂} {l₁ l₂ : α₁ →₀ β} :
id                             └┘  └┘           └┘ └┘ 
src                                                └┘
typ                            └┘  └┘           └┘ └┘ 
doc                                                 └┘
280    emb_domain f l₁ = emb_domain f l₂ ↔ l₁ = l₂ :=
id     └────────┘  └┘  └────────┘  └┘  └┘  └┘
src    └────────┘       └────────┘          
typ    └────────┘  └┘  └────────┘  └┘  └┘  └┘
doc    └────────┘        └────────┘
281  ⟨λ h, finsupp.ext $ λ a, by simpa [emb_domain_apply] using finsupp.ext_iff.1 h (f a),
id        └─────────┘                 └──────────────┘        └─────────────┘      
src        └─────────┘           └─────┘└──────────────┘└──────┘└─────────────┘└─┘    
typ       └─────────┘          └─────┘└──────────────┘└──────┘└─────────────┘└─┘ 
doc                              └─────┘                └──────┘               └─┘    
txt                              └─────┘                └──────┘               └─┘    
par                              └─────┘                └──────┘               └─┘    
pid                                                   └────┘               └─┘    
st                              └───────────────────────────────────────────────────────┘
282    λ h, by rw h⟩
id               
src            └─┘
typ           └─┘
doc            └─┘
txt            └─┘
par            └─┘
pid              
st            └───┘
283  
284  lemma emb_domain_map_range
285    {β₁ β₂ : Type*} [has_zero β₁] [has_zero β₂]
id                      └──────┘ └┘   └──────┘ └┘
src                     └──────┘      └──────┘
typ                     └──────┘ └┘   └──────┘ └┘
286    (f : α₁ ↪ α₂) (g : β₁ → β₂) (p : α₁ →₀ β₁) (hg : g 0 = 0) :
id          └┘  └┘       └┘   └┘       └┘ └┘ └┘           
src                                       └┘               
typ         └┘  └┘       └┘   └┘       └┘ └┘ └┘           
doc                                        └┘
287    emb_domain f (map_range g hg p) = map_range g hg (emb_domain f p) :=
id     └────────┘   └───────┘  └┘    └───────┘  └┘  └────────┘  
src    └────────┘    └───────┘          └───────┘       └────────┘
typ    └────────┘   └───────┘  └┘    └───────┘  └┘  └────────┘  
doc    └────────┘    └───────┘           └───────┘       └────────┘
288  begin
st   └─────
289    ext a,
src    └───┘
typ    └───┘
doc    └───┘
txt    └───┘
par    └───┘
pid       └┘
st   ──────┘└─
290    by_cases a ∈ set.range f,
id                └───────┘ 
src    └───────┘ └───────┘
typ    └───────┘└───────┘
doc    └───────┘  └───────┘
txt    └───────┘           
par    └───────┘           
pid                       
st   ─────────────────────────┘└─
291    { rcases h with ⟨a', rfl⟩,
id              
src      └─────┘ └─────────────┘
typ      └─────┘└─────────────┘
doc      └─────┘ └─────────────┘
txt      └─────┘ └─────────────┘
par      └─────┘ └─────────────┘
pid             └─────────────┘
st   ───┘└─────────────────────┘└─
292      rw [map_range_apply, emb_domain_apply, emb_domain_apply, map_range_apply] },
id           └─────────────┘  └──────────────┘  └──────────────┘  └─────────────┘
src      └──┘└─────────────┘└┘└──────────────┘└┘└──────────────┘└┘└─────────────┘└┘
typ      └──┘└─────────────┘└┘└──────────────┘└┘└──────────────┘└┘└─────────────┘└┘
doc      └──┘               └┘                └┘                └┘               └┘
txt      └──┘               └┘                └┘                └┘               └┘
par      └──┘               └┘                └┘                └┘               └┘
pid        └┘               └┘                └┘                └┘               
st   ──────────────────────┘└────────────────┘└────────────────┘└───────────────┘└┘
293    { rw [map_range_apply, emb_domain_notin_range, emb_domain_notin_range, ← hg]; assumption }
id           └─────────────┘  └────────────────────┘  └────────────────────┘    └┘
src      └──┘└─────────────┘└┘└────────────────────┘└┘└────────────────────┘└──┘    └─────────┘
typ      └──┘└─────────────┘└┘└────────────────────┘└┘└────────────────────┘└──┘└┘  └─────────┘
doc      └──┘               └┘                      └┘                      └──┘    └─────────┘
txt      └──┘               └┘                      └┘                      └──┘    └─────────┘
par      └──┘               └┘                      └┘                      └──┘    └─────────┘
pid        └┘               └┘                      └┘                      └──┘              
st   ──────────────────────┘└──────────────────────┘└──────────────────────┘└────┘└───────────┘└─
294  end
st   ──┘
295  
296  lemma single_of_emb_domain_single
297    (l : α₁ →₀ β) (f : α₁ ↪ α₂) (a : α₂) (b : β) (hb : b ≠ 0)
id          └┘ └┘        └┘  └┘       └┘                
src            └┘                                          
typ         └┘ └┘        └┘  └┘       └┘                
doc            └┘
298    (h : l.emb_domain f = finsupp.single a b) :
id          └─────────┘   └────────────┘  
src          └─────────┘    └────────────┘
typ         └─────────┘   └────────────┘  
doc          └─────────┘     └────────────┘
299    ∃ x, l = finsupp.single x b ∧ f x = a :=
id         └────────────┘       
src          └────────────┘          
typ        └────────────┘       
doc             └────────────┘
300  begin
st   └─────
301    have h_map_support : finset.map f (l.support) = finset.singleton a,
id                          └────────┘   └───────┘   └──────────────┘ 
src    └───────────────────┘└────────┘  └───────┘└┘└──────────────┘
typ    └───────────────────┘└────────┘ └───────┘└┘└──────────────┘
doc    └───────────────────┘                     └┘ └──────────────┘
txt    └───────────────────┘                     └┘                 
par    └───────────────────┘                     └┘                 
pid    └────────────────┘└─┘                     └┘                 
st   ───────────────────────────────────────────────────────────────────┘
302      by rw [←finsupp.support_emb_domain, h, finsupp.support_single_ne_zero hb]; refl,
id               └────────────────────────┘    └────────────────────────────┘ └┘
src         └───┘└────────────────────────┘└┘ └┘└────────────────────────────┘    └──┘
typ         └───┘└────────────────────────┘└┘└┘└────────────────────────────┘└┘  └──┘
doc         └───┘                          └┘ └┘                                  └──┘
txt         └───┘                          └┘ └┘                                  └──┘
par         └───┘                          └┘ └┘                                  └──┘
pid           └─┘                          └┘ └┘                                
st              └─────────────────────────┘└─┘└─────────────────────────────────┘      └─
303    have ha : a ∈ finset.map f (l.support),
id                 └────────┘   └───────┘
src    └────────┘ └────────┘  └───────┘
typ    └────────┘└────────┘ └───────┘
doc    └────────┘                       
txt    └────────┘                       
par    └────────┘                       
pid    └─────┘└─┘                       
st   ───────────────────────────────────────┘
304      by simp [h_map_support],
id                └───────────┘
src         └────┘             
typ         └────┘└───────────┘
doc         └────┘             
txt         └────┘             
par         └────┘             
pid                          
st                              └─
305    rcases finset.mem_map.1 ha with ⟨c, hc₁, hc₂⟩,
id            └────────────┘   └┘
src    └─────┘└────────────┘└─┘  └─────────────────┘
typ    └─────┘└────────────┘└─┘└┘└─────────────────┘
doc    └─────┘              └─┘  └─────────────────┘
txt    └─────┘              └─┘  └─────────────────┘
par    └─────┘              └─┘  └─────────────────┘
pid                        └─┘  └─────────────────┘
st   ──────────────────────────────────────────────┘└─
306    use c,
id         
src    └──┘
typ    └──┘
doc    └──┘
txt    └──┘
par    └──┘
pid       
st   ──────┘└─
307    split,
src    └───┘
typ    └───┘
doc    └───┘
txt    └───┘
par    └───┘
st   ──────┘└─
308    { ext d,
src      └───┘
typ      └───┘
doc      └───┘
txt      └───┘
par      └───┘
pid         └┘
st   ───┘└───┘└─
309      rw [← finsupp.emb_domain_apply f l, h],
id             └──────────────────────┘    
src      └────┘└──────────────────────┘  └┘ 
typ      └────┘└──────────────────────┘└┘
doc      └────┘                          └┘ 
txt      └────┘                          └┘ 
par      └────┘                          └┘ 
pid        └──┘                          └┘ 
st   ─────────────────────────────────────┘└─┘└──
310      by_cases h_cases : c = d,
id                             
src      └───────┘       └─┘  
typ      └───────┘       └─┘ 
doc      └───────┘       └─┘  
txt      └───────┘       └─┘  
par      └───────┘       └─┘  
pid                     └─┘  
st   ───────────────────────────┘└─
311      { simp [h_cases.symm, hc₂] },
id                             └─┘
src        └────┘            └┘   └┘
typ        └────┘└──────────┘└┘└─┘└┘
doc        └────┘            └┘   └┘
txt        └────┘            └┘   └┘
par        └────┘            └┘   └┘
pid                        └┘   
st   ─────┘└───────────────────────┘└┘
312      { rw [finsupp.single_apply, finsupp.single_apply, if_neg, if_neg h_cases],
id             └──────────────────┘  └──────────────────┘  └────┘  └────┘ └─────┘
src        └──┘└──────────────────┘└┘└──────────────────┘└┘└────┘└┘└────┘       
typ        └──┘└──────────────────┘└┘└──────────────────┘└┘└────┘└┘└────┘└─────┘
doc        └──┘                    └┘                    └┘      └┘             
txt        └──┘                    └┘                    └┘      └┘             
par        └──┘                    └┘                    └┘      └┘             
pid          └┘                    └┘                    └┘      └┘             
st   ─────────────────────────────┘└────────────────────┘└──────┘└──────────────┘└──
313        by_contra hfd,
src        └───────────┘
typ        └───────────┘
doc        └───────────┘
txt        └───────────┘
par        └───────────┘
pid                 └──┘
st   ──────────────────┘└─
314        exact h_cases (f.inj (hc₂.trans hfd)) } },
id               └─────┘  └───┘  └───────┘ └─┘
src        └────┘        └───┘ └───────┘   └─┘
typ        └────┘└─────┘ └───┘ └───────┘└─┘└─┘
doc        └────┘                          └─┘
txt        └────┘                          └─┘
par        └────┘                          └─┘
pid                                       └┘
st   ───────────────────────────────────────────┘└──┘
315    { exact hc₂ }
id             └─┘
src      └────┘   
typ      └────┘└─┘
doc      └────┘   
txt      └────┘   
par      └────┘   
pid              
st   ─────────────┘└─
316  end
st   ──┘
317  
318  end emb_domain
319  
320  section zip_with
321  variables [has_zero β] [has_zero β₁] [has_zero β₂]
id              └──────┘     └──────┘      └──────┘
src             └──────┘     └──────┘      └──────┘
typ             └──────┘     └──────┘      └──────┘
322  
323  /-- `zip_with f hf g₁ g₂` is the finitely supported function satisfying
324    `zip_with f hf g₁ g₂ a = f (g₁ a) (g₂ a)`, and well defined when `f 0 0 = 0`. -/
325  def zip_with (f : β₁ → β₂ → β) (hf : f 0 0 = 0) (g₁ : α →₀ β₁) (g₂ : α →₀ β₂) : (α →₀ β) :=
id                     └┘   └┘                           └┘ └┘         └┘ └┘      └┘ 
src                                                         └┘             └┘          └┘
typ                    └┘   └┘                           └┘ └┘         └┘ └┘      └┘ 
doc                                                          └┘             └┘          └┘
326  on_finset (g₁.support ∪ g₂.support) (λa, f (g₁ a) (g₂ a)) $ λ a H, begin
id   └───────┘  └┘└──────┘  └┘└──────┘        └┘    └┘         
src  └───────┘    └──────┘    └──────┘
typ  └───────┘  └┘└──────┘  └┘└──────┘        └┘    └┘         
doc  └───────┘
st                                                                      └─────
327    simp only [mem_union, mem_support_iff, ne], rw [← not_and_distrib],
id                └───────┘  └─────────────┘  └┘         └─────────────┘
src    └─────────┘└───────┘└┘└─────────────┘└┘└┘  └────┘└─────────────┘
typ    └─────────┘└───────┘└┘└─────────────┘└┘└┘  └────┘└─────────────┘
doc    └─────────┘         └┘               └┘    └────┘               
txt    └─────────┘         └┘               └┘    └────┘               
par    └─────────┘         └┘               └┘    └────┘               
pid        └──┘└┘         └┘               └┘      └──┘               
st   ───────────────────────────────────────────┘└─────────────────────┘└──
328    rintro ⟨h₁, h₂⟩, rw [h₁, h₂] at H, exact H hf
id                          └┘  └┘               └┘
src    └─────────────┘  └──┘  └┘  └────┘  └────┘   
typ    └─────────────┘  └──┘└┘└┘└┘└────┘  └────┘└┘
doc    └─────────────┘  └──┘  └┘  └────┘  └────┘   
txt    └─────────────┘  └──┘  └┘  └────┘  └────┘   
par    └─────────────┘  └──┘  └┘  └────┘  └────┘   
pid          └───────┘    └┘  └┘  └───┘          
st   ────────────────┘└──────┘└──┘└───┘└───────────┘
329  end
st   └─┘
330  
331  @[simp] lemma zip_with_apply
doc    └──┘
332    {f : β₁ → β₂ → β} {hf : f 0 0 = 0} {g₁ : α →₀ β₁} {g₂ : α →₀ β₂} {a : α} :
id          └┘   └┘                           └┘ └┘         └┘ └┘       
src                                              └┘             └┘
typ         └┘   └┘                           └┘ └┘         └┘ └┘       
doc                                               └┘             └┘
333    zip_with f hf g₁ g₂ a = f (g₁ a) (g₂ a) := rfl
id     └──────┘  └┘ └┘ └┘     └┘    └┘      └─┘
src    └──────┘                                  └─┘
typ    └──────┘  └┘ └┘ └┘     └┘    └┘      └─┘
doc    └──────┘
334  
335  lemma support_zip_with {f : β₁ → β₂ → β} {hf : f 0 0 = 0} {g₁ : α →₀ β₁} {g₂ : α →₀ β₂} :
id                               └┘   └┘                           └┘ └┘         └┘ └┘
src                                                                   └┘             └┘
typ                              └┘   └┘                           └┘ └┘         └┘ └┘
doc                                                                    └┘             └┘
336    (zip_with f hf g₁ g₂).support ⊆ g₁.support ∪ g₂.support :=
id      └──────┘  └┘ └┘ └┘ └─────┘   └┘└──────┘  └┘└──────┘
src     └──────┘            └─────┘     └──────┘    └──────┘
typ     └──────┘  └┘ └┘ └┘ └─────┘   └┘└──────┘  └┘└──────┘
doc     └──────┘
337  support_on_finset_subset
id   └──────────────────────┘
src  └──────────────────────┘
typ  └──────────────────────┘
338  
339  end zip_with
340  
341  section erase
342  
343  def erase [has_zero β] (a : α) (f : α →₀ β) : α →₀ β :=
id              └──────┘                └┘      └┘ 
src             └──────┘                   └┘        └┘
typ             └──────┘                └┘      └┘ 
doc                                        └┘        └┘
344  ⟨f.support.erase a, (λa', if a' = a then 0 else f a'),
id    └──────┘└────┘     └┘     └┘                └┘
src    └──────┘└────┘                
typ   └──────┘└────┘     └┘     └┘                └┘
doc            └────┘
345    assume a', by rw [mem_erase, mem_support_iff]; split_ifs;
id            └┘         └───────┘  └─────────────┘
src                  └──┘└───────┘└┘└─────────────┘  └───────┘
typ           └┘     └──┘└───────┘└┘└─────────────┘  └───────┘
doc                  └──┘         └┘                 └───────┘
txt                  └──┘         └┘                 └───────┘
par                  └──┘         └┘                 └───────┘
pid                    └┘         └┘               
st                  └────────────┘└───────────────┘└────────────
346      [exact ⟨λ H _, H.1 h, λ H, (H rfl).elim⟩,
id                                   └─┘
src      └────┘  └────┘ └─┘ └┘ └──┘  └─┘└─────┘
typ      └────┘  └────┘ └─┘└┘ └──┘  └─┘└─────┘
doc       └────┘  └────┘ └─┘ └┘ └──┘     └─────┘
txt       └────┘  └────┘ └─┘ └┘ └──┘     └─────┘
par       └────┘  └────┘ └─┘ └┘ └──┘     └─────┘
pid              └────┘ └─┘ └┘ └──┘     └─────┘
st   ──────────────────────────────────────────────
347      exact and_iff_right h]⟩
id             └───────────┘ 
src      └────┘└───────────┘
typ      └────┘└───────────┘
doc      └────┘             
txt      └────┘             
par      └────┘             
pid                        
st   ─────────────────────────┘
348  
349  @[simp] lemma support_erase [has_zero β] {a : α} {f : α →₀ β} :
id                                └──────┘                └┘ 
src                               └──────┘                   └┘
typ                               └──────┘                └┘ 
doc    └──┘                                                  └┘
350    (f.erase a).support = f.support.erase a :=
id      └────┘  └─────┘   └──────┘└────┘ 
src      └────┘   └─────┘    └──────┘└────┘
typ     └────┘  └─────┘   └──────┘└────┘ 
doc                                   └────┘
351  rfl
id   └─┘
src  └─┘
typ  └─┘
352  
353  @[simp] lemma erase_same [has_zero β] {a : α} {f : α →₀ β} : (f.erase a) a = 0 :=
id                             └──────┘                └┘      └────┘    
src                            └──────┘                   └┘        └────┘      
typ                            └──────┘                └┘      └────┘    
doc    └──┘                                               └┘
354  if_pos rfl
id   └────┘ └─┘
src  └────┘ └─┘
typ  └────┘ └─┘
355  
356  @[simp] lemma erase_ne [has_zero β] {a a' : α} {f : α →₀ β} (h : a' ≠ a) : (f.erase a) a' = f a' :=
id                           └──────┘                   └┘        └┘       └────┘   └┘   └┘
src                          └──────┘                      └┘                    └────┘       
typ                          └──────┘                   └┘        └┘       └────┘   └┘   └┘
doc    └──┘                                                └┘
357  if_neg h
id   └────┘ 
src  └────┘
typ  └────┘ 
358  
359  end erase
360  
361  -- [to_additive sum] for finsupp.prod doesn't work, the equation lemmas are not generated
362  /-- `sum f g` is the sum of `g a (f a)` over the support of `f`. -/
363  def sum [has_zero β] [add_comm_monoid γ] (f : α →₀ β) (g : α → β → γ) : γ :=
id            └──────┘    └─────────────┘         └┘                  
src           └──────┘     └─────────────┘           └┘
typ           └──────┘    └─────────────┘         └┘                  
doc                                                  └┘
364  f.support.sum (λa, g a (f a))
id   └──────┘└──┘         
src   └──────┘└──┘
typ  └──────┘└──┘         
365  
366  /-- `prod f g` is the product of `g a (f a)` over the support of `f`. -/
367  @[to_additive]
doc    └─────────┘
368  def prod [has_zero β] [comm_monoid γ] (f : α →₀ β) (g : α → β → γ) : γ :=
id             └──────┘    └─────────┘         └┘                  
src            └──────┘     └─────────┘           └┘
typ            └──────┘    └─────────┘         └┘                  
doc                                               └┘
369  f.support.prod (λa, g a (f a))
id   └──────┘└───┘         
src   └──────┘└───┘
typ  └──────┘└───┘         
doc           └───┘
370  
371  @[to_additive]
doc    └─────────┘
372  lemma prod_map_range_index [has_zero β₁] [has_zero β₂] [comm_monoid γ]
id                               └──────┘ └┘   └──────┘ └┘   └─────────┘ 
src                              └──────┘      └──────┘      └─────────┘
typ                              └──────┘ └┘   └──────┘ └┘   └─────────┘ 
373    {f : β₁ → β₂} {hf : f 0 = 0} {g : α →₀ β₁} {h : α → β₂ → γ} (h0 : ∀a, h a 0 = 1) :
id          └┘   └┘                     └┘ └┘          └┘                  
src                                       └┘                                      
typ         └┘   └┘                     └┘ └┘          └┘                  
doc                                        └┘
374    (map_range f hf g).prod h = g.prod (λa b, h a (f b)) :=
id      └───────┘  └┘  └──┘    └───┘          
src     └───────┘        └──┘      └───┘
typ     └───────┘  └┘  └──┘    └───┘          
doc     └───────┘        └──┘       └───┘
375  finset.prod_subset support_map_range $ λ _ _ H,
id   └────────────────┘ └───────────────┘       
src  └────────────────┘ └───────────────┘
typ  └────────────────┘ └───────────────┘       
376  by rw [not_mem_support_iff.1 H, h0]
id          └─────────────────┘     └┘
src     └──┘└─────────────────┘└─┘ └┘  └─
typ     └──┘└─────────────────┘└─┘└┘└┘└─
doc     └──┘                   └─┘ └┘  └─
txt     └──┘                   └─┘ └┘  └─
par     └──┘                   └─┘ └┘  └─
pid       └┘                   └─┘ └┘  
st     └──────────────────────────┘└──┘
377  
src  
typ  
doc  
txt  
par  
pid  
st   
378  @[to_additive]
doc    └─────────┘
379  lemma prod_zero_index [add_comm_monoid β] [comm_monoid γ] {h : α → β → γ} :
id                          └─────────────┘    └─────────┘              
src                         └─────────────┘     └─────────┘
typ                         └─────────────┘    └─────────┘              
380    (0 : α →₀ β).prod h = 1 := rfl
id           └┘  └──┘         └─┘
src           └┘   └──┘          └─┘
typ          └┘  └──┘         └─┘
doc           └┘   └──┘
381  
382  section nat_sub
383  instance nat_sub : has_sub (α →₀ ℕ) := ⟨zip_with (λ m n, m - n) (nat.sub_zero 0)⟩
id                      └─────┘   └┘       └──────┘            └──────────┘
src                     └─────┘    └┘       └──────┘                └──────────┘
typ                     └─────┘   └┘       └──────┘            └──────────┘
doc                                └┘        └──────┘
384  
385  @[simp] lemma nat_sub_apply {g₁ g₂ : α →₀ ℕ} {a : α} :
id                                         └┘        
src                                         └┘ 
typ                                        └┘        
doc    └──┘                                 └┘
386    (g₁ - g₂) a = g₁ a - g₂ a := rfl
id      └┘  └┘    └┘   └┘     └─┘
src                              └─┘
typ     └┘  └┘    └┘   └┘     └─┘
387  
388  end nat_sub
389  
390  section add_monoid
391  variables [add_monoid β]
id              └────────┘
src             └────────┘
typ             └────────┘
392  
393  @[to_additive]
doc    └─────────┘
394  lemma prod_single_index [comm_monoid γ] {a : α} {b : β} {h : α → β → γ} (h_zero : h a 0 = 1) :
id                            └─────────┘                                            
src                           └─────────┘                                                    
typ                           └─────────┘                                            
395    (single a b).prod h = h a b :=
id      └────┘   └──┘      
src     └────┘     └──┘    
typ     └────┘   └──┘      
doc     └────┘     └──┘
396  begin
st   └─────
397    by_cases h : b = 0,
id                   
src    └───────┘ └─┘ └┘
typ    └───────┘ └─┘└┘
doc    └───────┘ └─┘  └┘
txt    └───────┘ └─┘  └┘
par    └───────┘ └─┘  └┘
pid             └─┘  
st   ───────────────────┘└─
398    { simp only [h, h_zero, single_zero]; refl },
id                    └────┘  └─────────┘
src      └─────────┘ └┘      └┘└─────────┘  └───┘
typ      └─────────┘└┘└────┘└┘└─────────┘  └───┘
doc      └─────────┘ └┘      └┘             └───┘
txt      └─────────┘ └┘      └┘             └───┘
par      └─────────┘ └┘      └┘             └───┘
pid          └──┘└┘ └┘      └┘                 
st   ───┘└───────────────────────────────────────┘└┘
399    { simp only [finsupp.prod, support_single_ne_zero h, insert_empty_eq_singleton,
id                  └──────────┘  └────────────────────┘   └───────────────────────┘
src      └─────────┘└──────────┘└┘└────────────────────┘ └┘└───────────────────────┘└─
typ      └─────────┘└──────────┘└┘└────────────────────┘└┘└───────────────────────┘└─
doc      └─────────┘└──────────┘└┘                       └┘                         └─
txt      └─────────┘            └┘                       └┘                         └─
par      └─────────┘            └┘                       └┘                         └─
pid          └──┘└┘            └┘                       └┘                         └─
st   ──────────────────────────────────────────────────────────────────────────────────
400        prod_singleton, single_eq_same] }
id         └────────────┘  └────────────┘
src  ─────┘└────────────┘└┘└────────────┘└┘
typ  ─────┘└────────────┘└┘└────────────┘└┘
doc  ─────┘              └┘              └┘
txt  ─────┘              └┘              └┘
par  ─────┘              └┘              └┘
pid  ─────┘              └┘              
st   ─────────────────────────────────────┘└─
401  end
st   ──┘
402  
403  instance : has_add (α →₀ β) := ⟨zip_with (+) (add_zero 0)⟩
id              └─────┘   └┘       └──────┘     └──────┘
src             └─────┘    └┘        └──────┘     └──────┘
typ             └─────┘   └┘       └──────┘     └──────┘
doc                        └┘        └──────┘
404  
405  @[simp] lemma add_apply {g₁ g₂ : α →₀ β} {a : α} : (g₁ + g₂) a = g₁ a + g₂ a :=
id                                     └┘             └┘  └┘    └┘   └┘ 
src                                     └┘                               
typ                                    └┘             └┘  └┘    └┘   └┘ 
doc    └──┘                             └┘
406  rfl
id   └─┘
src  └─┘
typ  └─┘
407  
408  lemma support_add {g₁ g₂ : α →₀ β} : (g₁ + g₂).support ⊆ g₁.support ∪ g₂.support :=
id                               └┘      └┘  └┘ └─────┘   └┘└──────┘  └┘└──────┘
src                               └┘              └─────┘     └──────┘    └──────┘
typ                              └┘      └┘  └┘ └─────┘   └┘└──────┘  └┘└──────┘
doc                               └┘
409  support_zip_with
id   └──────────────┘
src  └──────────────┘
typ  └──────────────┘
410  
411  lemma support_add_eq {g₁ g₂ : α →₀ β} (h : disjoint g₁.support g₂.support) :
id                                  └┘        └──────┘ └┘└──────┘ └┘└──────┘
src                                  └┘         └──────┘   └──────┘   └──────┘
typ                                 └┘        └──────┘ └┘└──────┘ └┘└──────┘
doc                                  └┘         └──────┘
412    (g₁ + g₂).support = g₁.support ∪ g₂.support :=
id      └┘  └┘ └─────┘   └┘└──────┘  └┘└──────┘
src            └─────┘     └──────┘    └──────┘
typ     └┘  └┘ └─────┘   └┘└──────┘  └┘└──────┘
413  le_antisymm support_zip_with $ assume a ha,
id   └─────────┘ └──────────────┘           └┘
src  └─────────┘ └──────────────┘
typ  └─────────┘ └──────────────┘           └┘
414  (finset.mem_union.1 ha).elim
id    └──────────────┘  └┘ └──┘
src   └──────────────┘     └──┘
typ   └──────────────┘  └┘ └──┘
415    (assume ha, have a ∉ g₂.support, from disjoint_left.1 h ha,
id             └┘         └┘└──────┘       └───────────┘   └┘
src                          └──────┘       └───────────┘
typ            └┘         └┘└──────┘       └───────────┘   └┘
416      by simp only [mem_support_iff, not_not] at *;
id                     └─────────────┘  └─────┘
src         └─────────┘└─────────────┘└┘└─────┘└────┘
typ         └─────────┘└─────────────┘└┘└─────┘└────┘
doc         └─────────┘               └┘       └────┘
txt         └─────────┘               └┘       └────┘
par         └─────────┘               └┘       └────┘
pid             └──┘└┘               └┘       └──┘
st         └───────────────────────────────────────────
417      simpa only [add_apply, this, add_zero])
id                   └───────┘  └──┘  └──────┘
src      └──────────┘└───────┘└┘    └┘└──────┘
typ      └──────────┘└───────┘└┘└──┘└┘└──────┘
doc      └──────────┘         └┘    └┘        
txt      └──────────┘         └┘    └┘        
par      └──────────┘         └┘    └┘        
pid           └──┘└┘         └┘    └┘        
st   ─────────────────────────────────────────┘
418    (assume ha, have a ∉ g₁.support, from disjoint_right.1 h ha,
id             └┘         └┘└──────┘       └────────────┘   └┘
src                          └──────┘       └────────────┘
typ            └┘         └┘└──────┘       └────────────┘   └┘
419      by simp only [mem_support_iff, not_not] at *;
id                     └─────────────┘  └─────┘
src         └─────────┘└─────────────┘└┘└─────┘└────┘
typ         └─────────┘└─────────────┘└┘└─────┘└────┘
doc         └─────────┘               └┘       └────┘
txt         └─────────┘               └┘       └────┘
par         └─────────┘               └┘       └────┘
pid             └──┘└┘               └┘       └──┘
st         └───────────────────────────────────────────
420      simpa only [add_apply, this, zero_add])
id                   └───────┘  └──┘  └──────┘
src      └──────────┘└───────┘└┘    └┘└──────┘
typ      └──────────┘└───────┘└┘└──┘└┘└──────┘
doc      └──────────┘         └┘    └┘        
txt      └──────────┘         └┘    └┘        
par      └──────────┘         └┘    └┘        
pid           └──┘└┘         └┘    └┘        
st   ─────────────────────────────────────────┘
421  
422  @[simp] lemma single_add {a : α} {b₁ b₂ : β} : single a (b₁ + b₂) = single a b₁ + single a b₂ :=
id                                                └────┘   └┘  └┘   └────┘  └┘  └────┘  └┘
src                                                 └────┘             └────┘       └────┘
typ                                               └────┘   └┘  └┘   └────┘  └┘  └────┘  └┘
doc    └──┘                                         └────┘               └────┘        └────┘
423  ext $ assume a',
id   └─┘          └┘
src  └─┘
typ  └─┘          └┘
424  begin
st   └─────
425    by_cases h : a = a',
id                    └┘
src    └───────┘ └─┘ 
typ    └───────┘ └─┘└┘
doc    └───────┘ └─┘  
txt    └───────┘ └─┘  
par    └───────┘ └─┘  
pid             └─┘  
st   ────────────────────┘└─
426    { rw [h, add_apply, single_eq_same, single_eq_same, single_eq_same] },
id             └───────┘  └────────────┘  └────────────┘  └────────────┘
src      └──┘ └┘└───────┘└┘└────────────┘└┘└────────────┘└┘└────────────┘└┘
typ      └──┘└┘└───────┘└┘└────────────┘└┘└────────────┘└┘└────────────┘└┘
doc      └──┘ └┘         └┘              └┘              └┘              └┘
txt      └──┘ └┘         └┘              └┘              └┘              └┘
par      └──┘ └┘         └┘              └┘              └┘              └┘
pid        └┘ └┘         └┘              └┘              └┘              
st   ───┘└───┘└─────────┘└──────────────┘└──────────────┘└──────────────┘└┘
427    { rw [add_apply, single_eq_of_ne h, single_eq_of_ne h, single_eq_of_ne h, zero_add] }
id           └───────┘  └─────────────┘   └─────────────┘   └─────────────┘   └──────┘
src      └──┘└───────┘└┘└─────────────┘ └┘└─────────────┘ └┘└─────────────┘ └┘└──────┘└┘
typ      └──┘└───────┘└┘└─────────────┘└┘└─────────────┘└┘└─────────────┘└┘└──────┘└┘
doc      └──┘         └┘                └┘                └┘                └┘        └┘
txt      └──┘         └┘                └┘                └┘                └┘        └┘
par      └──┘         └┘                └┘                └┘                └┘        └┘
pid        └┘         └┘                └┘                └┘                └┘        
st   ────────────────┘└─────────────────┘└─────────────────┘└─────────────────┘└────────┘└─
428  end
st   ──┘
429  
430  instance : add_monoid (α →₀ β) :=
id              └────────┘   └┘ 
src             └────────┘    └┘
typ             └────────┘   └┘ 
doc                           └┘
431  { add_monoid .
432    zero      := 0,
433    add       := (+),
id                  
src                 
typ                 
434    add_assoc := assume ⟨s, f, hf⟩ ⟨t, g, hg⟩ ⟨u, h, hh⟩, ext $ assume a, add_assoc _ _ _,
id                                                        └─┘            └───────┘
src                                                          └─┘             └───────┘
typ                                                       └─┘            └───────┘
435    zero_add  := assume ⟨s, f, hf⟩, ext $ assume a, zero_add _,
id                                    └─┘            └──────┘
src                                    └─┘             └──────┘
typ                                   └─┘            └──────┘
436    add_zero  := assume ⟨s, f, hf⟩, ext $ assume a, add_zero _ }
id                                    └─┘            └──────┘
src                                    └─┘             └──────┘
typ                                   └─┘            └──────┘
437  
438  instance (a : α) : is_add_monoid_hom (λ g : α →₀ β, g a) :=
id                     └───────────────┘         └┘    
src                     └───────────────┘          └┘
typ                    └───────────────┘         └┘    
doc                     └───────────────┘          └┘
439  { map_add := λ _ _, add_apply, map_zero := zero_apply }
id                     └───────┘              └────────┘
src                      └───────┘              └────────┘
typ                    └───────┘              └────────┘
440  
441  lemma single_add_erase {a : α} {f : α →₀ β} : single a (f a) + f.erase a = f :=
id                                       └┘     └────┘       └────┘   
src                                        └┘      └────┘           └────┘   
typ                                      └┘     └────┘       └────┘   
doc                                        └┘      └────┘
442  ext $ λ a',
id   └─┘     └┘
src  └─┘
typ  └─┘     └┘
443  if h : a = a' then by subst h; simp only [add_apply, single_eq_same, erase_same, add_zero]
id   └┘       └┘                            └───────┘  └────────────┘  └────────┘  └──────┘
src  └┘                   └────┘   └─────────┘└───────┘└┘└────────────┘└┘└────────┘└┘└──────┘└┘
typ  └┘       └┘         └────┘  └─────────┘└───────┘└┘└────────────┘└┘└────────┘└┘└──────┘└┘
doc                        └────┘   └─────────┘         └┘              └┘          └┘        └┘
txt                        └────┘   └─────────┘         └┘              └┘          └┘        └┘
par                        └────┘   └─────────┘         └┘              └┘          └┘        └┘
pid                                    └──┘└┘         └┘              └┘          └┘        
st                        └────────────────────────────────────────────────────────────────────┘
444  else by simp only [add_apply, single_eq_of_ne h, zero_add, erase_ne (ne.symm h)]
id                      └───────┘  └─────────────┘   └──────┘  └──────┘  └─────┘ 
src          └─────────┘└───────┘└┘└─────────────┘ └┘└──────┘└┘└──────┘ └─────┘ └──
typ          └─────────┘└───────┘└┘└─────────────┘└┘└──────┘└┘└──────┘ └─────┘└──
doc          └─────────┘         └┘                └┘        └┘                 └──
txt          └─────────┘         └┘                └┘        └┘                 └──
par          └─────────┘         └┘                └┘        └┘                 └──
pid              └──┘└┘         └┘                └┘        └┘                 └┘
st          └─────────────────────────────────────────────────────────────────────────
445  
src  
typ  
doc  
txt  
par  
pid  
st   
446  lemma erase_add_single {a : α} {f : α →₀ β} : f.erase a + single a (f a) = f :=
id                                       └┘     └────┘   └────┘       
src                                        └┘       └────┘    └────┘         
typ                                      └┘     └────┘   └────┘       
doc                                        └┘                  └────┘
447  ext $ λ a',
id   └─┘     └┘
src  └─┘
typ  └─┘     └┘
448  if h : a = a' then by subst h; simp only [add_apply, single_eq_same, erase_same, zero_add]
id   └┘       └┘                            └───────┘  └────────────┘  └────────┘  └──────┘
src  └┘                   └────┘   └─────────┘└───────┘└┘└────────────┘└┘└────────┘└┘└──────┘└┘
typ  └┘       └┘         └────┘  └─────────┘└───────┘└┘└────────────┘└┘└────────┘└┘└──────┘└┘
doc                        └────┘   └─────────┘         └┘              └┘          └┘        └┘
txt                        └────┘   └─────────┘         └┘              └┘          └┘        └┘
par                        └────┘   └─────────┘         └┘              └┘          └┘        └┘
pid                                    └──┘└┘         └┘              └┘          └┘        
st                        └────────────────────────────────────────────────────────────────────┘
449  else by simp only [add_apply, single_eq_of_ne h, add_zero, erase_ne (ne.symm h)]
id                      └───────┘  └─────────────┘   └──────┘  └──────┘  └─────┘ 
src          └─────────┘└───────┘└┘└─────────────┘ └┘└──────┘└┘└──────┘ └─────┘ └──
typ          └─────────┘└───────┘└┘└─────────────┘└┘└──────┘└┘└──────┘ └─────┘└──
doc          └─────────┘         └┘                └┘        └┘                 └──
txt          └─────────┘         └┘                └┘        └┘                 └──
par          └─────────┘         └┘                └┘        └┘                 └──
pid              └──┘└┘         └┘                └┘        └┘                 └┘
st          └─────────────────────────────────────────────────────────────────────────
450  
src  
typ  
doc  
txt  
par  
pid  
st   
451  @[elab_as_eliminator]
doc    └────────────────┘
452  protected theorem induction {p : (α →₀ β) → Prop} (f : α →₀ β)
id                                      └┘                 └┘ 
src                                      └┘                   └┘
typ                                     └┘                 └┘ 
doc                                      └┘                   └┘
453    (h0 : p 0) (ha : ∀a b (f : α →₀ β), a ∉ f.support → b ≠ 0 → p f → p (single a b + f)) :
id                              └┘      └──────┘               └────┘    
src                                 └┘         └──────┘                   └────┘     
typ                             └┘      └──────┘               └────┘    
doc                                 └┘                                      └────┘
454    p f :=
id      
typ     
455  suffices ∀s (f : α →₀ β), f.support = s → p f, from this _ _ rfl,
id                    └┘    └──────┘             └──┘     └─┘
src                     └┘      └──────┘                         └─┘
typ                   └┘    └──────┘             └──┘     └─┘
doc                     └┘
456  assume s, finset.induction_on s (λ f hf, by rwa [support_eq_empty.1 hf]) $
id            └─────────────────┘      └┘          └──────────────┘   └┘
src            └─────────────────┘               └───┘└──────────────┘└─┘  
typ           └─────────────────┘      └┘     └───┘└──────────────┘└─┘└┘
doc            └─────────────────┘               └───┘                └─┘  
txt                                              └───┘                └─┘  
par                                              └───┘                └─┘  
pid                                                 └┘                └─┘  
st                                              └─────────────────────────┘
457  assume a s has ih f hf,
id            └─┘ └┘  └┘
typ           └─┘ └┘  └┘
458  suffices p (single a (f a) + f.erase a), by rwa [single_add_erase] at this,
id              └────┘       └────┘            └──────────────┘
src              └────┘           └────┘        └───┘└──────────────┘└───────┘
typ             └────┘       └────┘       └───┘└──────────────┘└───────┘
doc              └────┘                          └───┘                └───────┘
txt                                              └───┘                └───────┘
par                                              └───┘                └───────┘
pid                                                 └┘                └──────┘
st                                              └────────────────────┘└──────┘
459  begin
st   └─────
460    apply ha,
src    └────┘
typ    └────┘
doc    └────┘
txt    └────┘
par    └────┘
pid         
st   ─────────┘└─
461    { rw [support_erase, mem_erase], exact λ H, H.1 rfl },
id           └───────────┘  └───────┘                  └─┘
src      └──┘└───────────┘└┘└───────┘  └────┘ └──┘ └─┘└─┘
typ      └──┘└───────────┘└┘└───────┘  └────┘ └──┘ └─┘└─┘
doc      └──┘             └┘           └────┘ └──┘ └─┘   
txt      └──┘             └┘           └────┘ └──┘ └─┘   
par      └──┘             └┘           └────┘ └──┘ └─┘   
pid        └┘             └┘                 └──┘ └─┘   
st   ───┘└───────────────┘└─────────┘└────────────────────┘└┘
462    { rw [← mem_support_iff, hf], exact mem_insert_self _ _ },
id             └─────────────┘  └┘         └─────────────┘
src      └────┘└─────────────┘└┘    └────┘└─────────────┘└───┘
typ      └────┘└─────────────┘└┘└┘  └────┘└─────────────┘└───┘
doc      └────┘               └┘    └────┘               └───┘
txt      └────┘               └┘    └────┘               └───┘
par      └────┘               └┘    └────┘               └───┘
pid        └──┘               └┘                        └──┘
st   ───┘└───────────────────┘└──┘└───────────────────────────┘└┘
463    { apply ih _ _,
id             └┘
src      └────┘  └──┘
typ      └────┘└┘└──┘
doc      └────┘  └──┘
txt      └────┘  └──┘
par      └────┘  └──┘
pid             └──┘
st   ───────────────┘└─
464      rw [support_erase, hf, finset.erase_insert has] }
id           └───────────┘  └┘  └─────────────────┘ └─┘
src      └──┘└───────────┘└┘  └┘└─────────────────┘   └┘
typ      └──┘└───────────┘└┘└┘└┘└─────────────────┘└─┘└┘
doc      └──┘             └┘  └┘                      └┘
txt      └──┘             └┘  └┘                      └┘
par      └──┘             └┘  └┘                      └┘
pid        └┘             └┘  └┘                      
st   ────────────────────┘└──┘└───────────────────────┘└─
465  end
st   ──┘
466  
467  lemma induction₂ {p : (α →₀ β) → Prop} (f : α →₀ β)
id                           └┘                 └┘ 
src                           └┘                   └┘
typ                          └┘                 └┘ 
doc                           └┘                   └┘
468    (h0 : p 0) (ha : ∀a b (f : α →₀ β), a ∉ f.support → b ≠ 0 → p f → p (f + single a b)) :
id                              └┘      └──────┘                 └────┘  
src                                 └┘         └──────┘                      └────┘
typ                             └┘      └──────┘                 └────┘  
doc                                 └┘                                          └────┘
469    p f :=
id      
typ     
470  suffices ∀s (f : α →₀ β), f.support = s → p f, from this _ _ rfl,
id                    └┘    └──────┘             └──┘     └─┘
src                     └┘      └──────┘                         └─┘
typ                   └┘    └──────┘             └──┘     └─┘
doc                     └┘
471  assume s, finset.induction_on s (λ f hf, by rwa [support_eq_empty.1 hf]) $
id            └─────────────────┘      └┘          └──────────────┘   └┘
src            └─────────────────┘               └───┘└──────────────┘└─┘  
typ           └─────────────────┘      └┘     └───┘└──────────────┘└─┘└┘
doc            └─────────────────┘               └───┘                └─┘  
txt                                              └───┘                └─┘  
par                                              └───┘                └─┘  
pid                                                 └┘                └─┘  
st                                              └─────────────────────────┘
472  assume a s has ih f hf,
id            └─┘ └┘  └┘
typ           └─┘ └┘  └┘
473  suffices p (f.erase a + single a (f a)), by rwa [erase_add_single] at this,
id              └────┘   └────┘                └──────────────┘
src               └────┘    └────┘              └───┘└──────────────┘└───────┘
typ             └────┘   └────┘           └───┘└──────────────┘└───────┘
doc                          └────┘              └───┘                └───────┘
txt                                              └───┘                └───────┘
par                                              └───┘                └───────┘
pid                                                 └┘                └──────┘
st                                              └────────────────────┘└──────┘
474  begin
st   └─────
475    apply ha,
src    └────┘
typ    └────┘
doc    └────┘
txt    └────┘
par    └────┘
pid         
st   ─────────┘└─
476    { rw [support_erase, mem_erase], exact λ H, H.1 rfl },
id           └───────────┘  └───────┘                  └─┘
src      └──┘└───────────┘└┘└───────┘  └────┘ └──┘ └─┘└─┘
typ      └──┘└───────────┘└┘└───────┘  └────┘ └──┘ └─┘└─┘
doc      └──┘             └┘           └────┘ └──┘ └─┘   
txt      └──┘             └┘           └────┘ └──┘ └─┘   
par      └──┘             └┘           └────┘ └──┘ └─┘   
pid        └┘             └┘                 └──┘ └─┘   
st   ───┘└───────────────┘└─────────┘└────────────────────┘└┘
477    { rw [← mem_support_iff, hf], exact mem_insert_self _ _ },
id             └─────────────┘  └┘         └─────────────┘
src      └────┘└─────────────┘└┘    └────┘└─────────────┘└───┘
typ      └────┘└─────────────┘└┘└┘  └────┘└─────────────┘└───┘
doc      └────┘               └┘    └────┘               └───┘
txt      └────┘               └┘    └────┘               └───┘
par      └────┘               └┘    └────┘               └───┘
pid        └──┘               └┘                        └──┘
st   ───┘└───────────────────┘└──┘└───────────────────────────┘└┘
478    { apply ih _ _,
id             └┘
src      └────┘  └──┘
typ      └────┘└┘└──┘
doc      └────┘  └──┘
txt      └────┘  └──┘
par      └────┘  └──┘
pid             └──┘
st   ───────────────┘└─
479      rw [support_erase, hf, finset.erase_insert has] }
id           └───────────┘  └┘  └─────────────────┘ └─┘
src      └──┘└───────────┘└┘  └┘└─────────────────┘   └┘
typ      └──┘└───────────┘└┘└┘└┘└─────────────────┘└─┘└┘
doc      └──┘             └┘  └┘                      └┘
txt      └──┘             └┘  └┘                      └┘
par      └──┘             └┘  └┘                      └┘
pid        └┘             └┘  └┘                      
st   ────────────────────┘└──┘└───────────────────────┘└─
480  end
st   ──┘
481  
482  lemma map_range_add [add_monoid β₁] [add_monoid β₂]
id                        └────────┘ └┘   └────────┘ └┘
src                       └────────┘      └────────┘
typ                       └────────┘ └┘   └────────┘ └┘
483    {f : β₁ → β₂} {hf : f 0 = 0} (hf' : ∀ x y, f (x + y) = f x + f y) (v₁ v₂ : α →₀ β₁) :
id          └┘   └┘                                                  └┘ └┘
src                                                                             └┘
typ         └┘   └┘                                                  └┘ └┘
doc                                                                                 └┘
484    map_range f hf (v₁ + v₂) = map_range f hf v₁ + map_range f hf v₂ :=
id     └───────┘  └┘  └┘  └┘   └───────┘  └┘ └┘  └───────┘  └┘ └┘
src    └───────┘                └───────┘          └───────┘
typ    └───────┘  └┘  └┘  └┘   └───────┘  └┘ └┘  └───────┘  └┘ └┘
doc    └───────┘                  └───────┘           └───────┘
485  finsupp.ext $ λ a, by simp [hf']
id   └─────────┘                └─┘
src  └─────────┘           └────┘   └─
typ  └─────────┘          └────┘└─┘└─
doc                        └────┘   └─
txt                        └────┘   └─
par                        └────┘   └─
pid                               
st                        └───────────
486  
src  
typ  
doc  
txt  
par  
pid  
st   
487  end add_monoid
488  
489  instance [add_comm_monoid β] : add_comm_monoid (α →₀ β) :=
id             └─────────────┘     └─────────────┘   └┘ 
src            └─────────────┘      └─────────────┘    └┘
typ            └─────────────┘     └─────────────┘   └┘ 
doc                                                    └┘
490  { add_comm := assume ⟨s, f, _⟩ ⟨t, g, _⟩, ext $ assume a, add_comm _ _,
id                                           └─┘            └──────┘
src                                            └─┘             └──────┘
typ                                          └─┘            └──────┘
491    .. finsupp.add_monoid }
id        └────────────────┘
src       └────────────────┘
typ       └────────────────┘
492  
493  instance [add_group β] : add_group (α →₀ β) :=
id             └───────┘     └───────┘   └┘ 
src            └───────┘      └───────┘    └┘
typ            └───────┘     └───────┘   └┘ 
doc                                        └┘
494  { neg          := map_range (has_neg.neg) neg_zero,
id                     └───────┘  └─────────┘  └──────┘
src                    └───────┘  └─────────┘  └──────┘
typ                    └───────┘  └─────────┘  └──────┘
doc                    └───────┘
495    add_left_neg := assume ⟨s, f, _⟩, ext $ assume x, add_left_neg _,
id                                      └─┘            └──────────┘
src                                      └─┘             └──────────┘
typ                                     └─┘            └──────────┘
496    .. finsupp.add_monoid }
id        └────────────────┘
src       └────────────────┘
typ       └────────────────┘
497  
498  lemma single_multiset_sum [add_comm_monoid β] (s : multiset β) (a : α) :
id                              └─────────────┘        └──────┘        
src                             └─────────────┘         └──────┘
typ                             └─────────────┘        └──────┘        
doc                                                     └──────┘
499    single a s.sum = (s.map (single a)).sum :=
id     └────┘  └──┘   └──┘  └────┘   └─┘
src    └────┘    └──┘    └──┘  └────┘    └─┘
typ    └────┘  └──┘   └──┘  └────┘   └─┘
doc    └────┘             └──┘  └────┘
500  multiset.induction_on s single_zero $ λ a s ih,
id   └───────────────────┘  └─────────┘       └┘
src  └───────────────────┘   └─────────┘
typ  └───────────────────┘  └─────────┘       └┘
501  by rw [multiset.sum_cons, single_add, ih, multiset.map_cons, multiset.sum_cons]
id          └───────────────┘  └────────┘  └┘  └───────────────┘  └───────────────┘
src     └──┘└───────────────┘└┘└────────┘└┘  └┘└───────────────┘└┘└───────────────┘└─
typ     └──┘└───────────────┘└┘└────────┘└┘└┘└┘└───────────────┘└┘└───────────────┘└─
doc     └──┘                 └┘          └┘  └┘                 └┘                 └─
txt     └──┘                 └┘          └┘  └┘                 └┘                 └─
par     └──┘                 └┘          └┘  └┘                 └┘                 └─
pid       └┘                 └┘          └┘  └┘                 └┘                 
st     └────────────────────┘└──────────┘└──┘└─────────────────┘└─────────────────┘
502  
src  
typ  
doc  
txt  
par  
pid  
st   
503  lemma single_finset_sum [add_comm_monoid β] (s : finset γ) (f : γ → β) (a : α) :
id                            └─────────────┘        └────┘                  
src                           └─────────────┘         └────┘
typ                           └─────────────┘        └────┘                  
doc                                                   └────┘
504    single a (s.sum f) = s.sum (λb, single a (f b)) :=
id     └────┘   └──┘    └──┘     └────┘    
src    └────┘     └──┘      └──┘      └────┘
typ    └────┘   └──┘    └──┘     └────┘    
doc    └────┘                          └────┘
505  begin
st   └─────
506    transitivity,
src    └──────────┘
typ    └──────────┘
doc    └──────────┘
txt    └──────────┘
par    └──────────┘
st   ─────────────┘└─
507    apply single_multiset_sum,
id           └─────────────────┘
src    └────┘└─────────────────┘
typ    └────┘└─────────────────┘
doc    └────┘
txt    └────┘
par    └────┘
pid         
st   ──────────────────────────┘└─
508    rw [multiset.map_map],
id         └──────────────┘
src    └──┘└──────────────┘
typ    └──┘└──────────────┘
doc    └──┘                
txt    └──┘                
par    └──┘                
pid      └┘                
st   ─────────────────────┘└──
509    refl
src    └───┘
typ    └───┘
doc    └───┘
txt    └───┘
par    └───┘
pid        
st   ──────┘
510  end
st   └─┘
511  
512  lemma single_sum [has_zero γ] [add_comm_monoid β] (s : δ →₀ γ) (f : δ → γ → β) (a : α) :
id                     └──────┘    └─────────────┘         └┘                     
src                    └──────┘     └─────────────┘           └┘
typ                    └──────┘    └─────────────┘         └┘                     
doc                                                           └┘
513    single a (s.sum f) = s.sum (λd c, single a (f d c)) :=
id     └────┘   └──┘    └──┘      └────┘     
src    └────┘     └──┘      └──┘        └────┘
typ    └────┘   └──┘    └──┘      └────┘     
doc    └────┘     └──┘       └──┘        └────┘
514  single_finset_sum _ _ _
id   └───────────────┘
src  └───────────────┘
typ  └───────────────┘
515  
516  
517  @[to_additive]
doc    └─────────┘
518  lemma prod_neg_index [add_group β] [comm_monoid γ]
id                         └───────┘    └─────────┘ 
src                        └───────┘     └─────────┘
typ                        └───────┘    └─────────┘ 
519    {g : α →₀ β} {h : α → β → γ} (h0 : ∀a, h a 0 = 1) :
id           └┘                             
src           └┘                                    
typ          └┘                             
doc           └┘
520    (-g).prod h = g.prod (λa b, h a (- b)) :=
id       └──┘    └───┘          
src       └──┘      └───┘             
typ      └──┘    └───┘          
doc        └──┘       └───┘
521  prod_map_range_index h0
id   └──────────────────┘ └┘
src  └──────────────────┘
typ  └──────────────────┘ └┘
522  
523  @[simp] lemma neg_apply [add_group β] {g : α →₀ β} {a : α} : (- g) a = - g a := rfl
id                            └───────┘         └┘                        └─┘
src                           └───────┘           └┘                              └─┘
typ                           └───────┘         └┘                        └─┘
doc    └──┘                                       └┘
524  
525  @[simp] lemma sub_apply [add_group β] {g₁ g₂ : α →₀ β} {a : α} : (g₁ - g₂) a = g₁ a - g₂ a := rfl
id                            └───────┘             └┘             └┘  └┘    └┘   └┘     └─┘
src                           └───────┘               └┘                                        └─┘
typ                           └───────┘             └┘             └┘  └┘    └┘   └┘     └─┘
doc    └──┘                                           └┘
526  
527  @[simp] lemma support_neg [add_group β] {f : α →₀ β} : support (-f) = support f :=
id                              └───────┘         └┘     └─────┘     └─────┘ 
src                             └───────┘           └┘      └─────┘      └─────┘
typ                             └───────┘         └┘     └─────┘     └─────┘ 
doc    └──┘                                         └┘
528  finset.subset.antisymm
id   └────────────────────┘
src  └────────────────────┘
typ  └────────────────────┘
529    support_map_range
id     └───────────────┘
src    └───────────────┘
typ    └───────────────┘
530    (calc support f = support (- (- f)) : congr_arg support (neg_neg _).symm
id           └─────┘    └─────┘          └───────┘ └─────┘  └─────┘   └──┘
src          └─────┘     └─────┘           └───────┘ └─────┘  └─────┘   └──┘
typ          └─────┘    └─────┘          └───────┘ └─────┘  └─────┘   └──┘
531       ... ⊆ support (- f) : support_map_range)
id              └─────┘       └───────────────┘
src             └─────┘        └───────────────┘
typ             └─────┘       └───────────────┘
532  
533  instance [add_comm_group β] : add_comm_group (α →₀ β) :=
id             └────────────┘     └────────────┘   └┘ 
src            └────────────┘      └────────────┘    └┘
typ            └────────────┘     └────────────┘   └┘ 
doc                                                  └┘
534  { add_comm := add_comm, ..finsupp.add_group }
id                 └──────┘    └───────────────┘
src                └──────┘    └───────────────┘
typ                └──────┘    └───────────────┘
535  
536  @[simp] lemma sum_apply [has_zero β₁] [add_comm_monoid β]
id                            └──────┘ └┘   └─────────────┘ 
src                           └──────┘      └─────────────┘
typ                           └──────┘ └┘   └─────────────┘ 
doc    └──┘
537    {f : α₁ →₀ β₁} {g : α₁ → β₁ → α →₀ β} {a₂ : α} :
id          └┘ └┘ └┘       └┘   └┘    └┘         
src            └┘                      └┘
typ         └┘ └┘ └┘       └┘   └┘    └┘         
doc            └┘                      └┘
538    (f.sum g) a₂ = f.sum (λa₁ b, g a₁ b a₂) :=
id      └──┘   └┘  └──┘   └┘    └┘  └┘
src      └──┘         └──┘
typ     └──┘   └┘  └──┘   └┘    └┘  └┘
doc      └──┘          └──┘
539  (f.support.sum_hom (λf : α →₀ β, f a₂)).symm
id    └──────┘└──────┘        └┘    └┘  └──┘
src    └──────┘└──────┘         └┘          └──┘
typ   └──────┘└──────┘        └┘    └┘  └──┘
doc                             └┘
540  
541  lemma support_sum [has_zero β₁] [add_comm_monoid β]
id                      └──────┘ └┘   └─────────────┘ 
src                     └──────┘      └─────────────┘
typ                     └──────┘ └┘   └─────────────┘ 
542    {f : α₁ →₀ β₁} {g : α₁ → β₁ → (α →₀ β)} :
id          └┘ └┘ └┘       └┘   └┘     └┘ 
src            └┘                       └┘
typ         └┘ └┘ └┘       └┘   └┘     └┘ 
doc            └┘                       └┘
543    (f.sum g).support ⊆ f.support.bind (λa, (g a (f a)).support) :=
id      └──┘  └─────┘   └──────┘└───┘            └─────┘
src      └──┘   └─────┘    └──────┘└───┘                 └─────┘
typ     └──┘  └─────┘   └──────┘└───┘            └─────┘
doc      └──┘                       └───┘
544  have ∀a₁ : α, f.sum (λ (a : α₁) (b : β₁), (g a b) a₁) ≠ 0 →
id                └──┘         └┘       └┘        └┘  
src                 └──┘                                   
typ               └──┘         └┘       └┘        └┘  
doc                 └──┘
545      (∃ (a : α₁), f a ≠ 0 ∧ ¬ (g a (f a)) a₁ = 0),
id              └┘                 └┘ 
src                                         
typ             └┘                 └┘ 
546    from assume a₁ h,
id                 └┘ 
typ                └┘ 
547    let ⟨a, ha, ne⟩ := finset.exists_ne_zero_of_sum_ne_zero h in
id     └─┘    └┘  └┘     └──────────────────────────────────┘ 
src                └┘     └──────────────────────────────────┘
typ    └─┘    └┘  └┘     └──────────────────────────────────┘ 
548    ⟨a, mem_support_iff.mp ha, ne⟩,
id         └─────────────┘└─┘
src        └─────────────┘└─┘
typ        └─────────────┘└─┘
549  by simpa only [finset.subset_iff, mem_support_iff, finset.mem_bind, sum_apply, exists_prop] using this
id                  └───────────────┘  └─────────────┘  └─────────────┘  └───────┘  └─────────┘        └──┘
src     └──────────┘└───────────────┘└┘└─────────────┘└┘└─────────────┘└┘└───────┘└┘└─────────┘└──────┘    
typ     └──────────┘└───────────────┘└┘└─────────────┘└┘└─────────────┘└┘└───────┘└┘└─────────┘└──────┘└──┘
doc     └──────────┘                 └┘               └┘               └┘         └┘           └──────┘    
txt     └──────────┘                 └┘               └┘               └┘         └┘           └──────┘    
par     └──────────┘                 └┘               └┘               └┘         └┘           └──────┘    
pid          └──┘└┘                 └┘               └┘               └┘         └┘           └────┘    
st     └────────────────────────────────────────────────────────────────────────────────────────────────────
550  
src  
typ  
doc  
txt  
par  
pid  
st   
551  @[simp] lemma sum_zero [add_comm_monoid β] [add_comm_monoid γ] {f : α →₀ β} :
id                           └─────────────┘    └─────────────┘         └┘ 
src                          └─────────────┘     └─────────────┘           └┘
typ                          └─────────────┘    └─────────────┘         └┘ 
doc    └──┘                                                                └┘
552    f.sum (λa b, (0 : γ)) = 0 :=
id     └──┘              
src     └──┘                 
typ    └──┘              
doc     └──┘
553  finset.sum_const_zero
id   └───────────────────┘
src  └───────────────────┘
typ  └───────────────────┘
554  
555  @[simp] lemma sum_add  [add_comm_monoid β] [add_comm_monoid γ] {f : α →₀ β}
id                           └─────────────┘    └─────────────┘         └┘ 
src                          └─────────────┘     └─────────────┘           └┘
typ                          └─────────────┘    └─────────────┘         └┘ 
doc    └──┘                                                                └┘
556    {h₁ h₂ : α → β → γ} :
id                    
typ                   
557    f.sum (λa b, h₁ a b + h₂ a b) = f.sum h₁ + f.sum h₂ :=
id     └──┘      └┘    └┘     └──┘ └┘  └──┘ └┘
src     └──┘                          └──┘      └──┘
typ    └──┘      └┘    └┘     └──┘ └┘  └──┘ └┘
doc     └──┘                            └──┘       └──┘
558  finset.sum_add_distrib
id   └────────────────────┘
src  └────────────────────┘
typ  └────────────────────┘
559  
560  @[simp] lemma sum_neg [add_comm_monoid β] [add_comm_group γ] {f : α →₀ β}
id                          └─────────────┘    └────────────┘         └┘ 
src                         └─────────────┘     └────────────┘           └┘
typ                         └─────────────┘    └────────────┘         └┘ 
doc    └──┘                                                              └┘
561    {h : α → β → γ} : f.sum (λa b, - h a b) = - f.sum h :=
id                    └──┘             └──┘ 
src                       └──┘                   └──┘
typ                   └──┘             └──┘ 
doc                       └──┘                      └──┘
562  f.support.sum_hom (@has_neg.neg γ _)
id   └──────┘└──────┘   └─────────┘ 
src   └──────┘└──────┘   └─────────┘
typ  └──────┘└──────┘   └─────────┘ 
563  
564  @[simp] lemma sum_sub [add_comm_monoid β] [add_comm_group γ] {f : α →₀ β}
id                          └─────────────┘    └────────────┘         └┘ 
src                         └─────────────┘     └────────────┘           └┘
typ                         └─────────────┘    └────────────┘         └┘ 
doc    └──┘                                                              └┘
565    {h₁ h₂ : α → β → γ} :
id                    
typ                   
566    f.sum (λa b, h₁ a b - h₂ a b) = f.sum h₁ - f.sum h₂ :=
id     └──┘      └┘    └┘     └──┘ └┘  └──┘ └┘
src     └──┘                          └──┘      └──┘
typ    └──┘      └┘    └┘     └──┘ └┘  └──┘ └┘
doc     └──┘                            └──┘       └──┘
567  by rw [sub_eq_add_neg, ←sum_neg, ←sum_add]; refl
id          └────────────┘   └─────┘   └─────┘
src     └──┘└────────────┘└─┘└─────┘└─┘└─────┘  └────
typ     └──┘└────────────┘└─┘└─────┘└─┘└─────┘  └────
doc     └──┘              └─┘       └─┘         └────
txt     └──┘              └─┘       └─┘         └────
par     └──┘              └─┘       └─┘         └────
pid       └┘              └─┘       └─┘             
st     └─────────────────┘└────────┘└────────┘└──────
568  
src  
typ  
doc  
txt  
par  
pid  
st   
569  @[simp] lemma sum_single [add_comm_monoid β] (f : α →₀ β) :
id                             └─────────────┘         └┘ 
src                            └─────────────┘           └┘
typ                            └─────────────┘         └┘ 
doc    └──┘                                              └┘
570    f.sum single = f :=
id     └──┘ └────┘  
src     └──┘ └────┘ 
typ    └──┘ └────┘  
doc     └──┘ └────┘
571  have ∀a:α, f.sum (λa' b, ite (a' = a) b 0) =
id             └──┘   └┘   └─┘  └┘        
src              └──┘         └─┘              
typ            └──┘   └┘   └─┘  └┘        
doc              └──┘
572      ({a} : finset α).sum (λa', ite (a' = a) (f a') 0),
id            └────┘  └─┘    └┘  └─┘  └┘      └┘
src            └────┘   └─┘        └─┘     
typ           └────┘  └─┘    └┘  └─┘  └┘      └┘
doc             └────┘
573  begin
st   └─────
574    intro a,
src    └─────┘
typ    └─────┘
doc    └─────┘
txt    └─────┘
par    └─────┘
pid         └┘
st   ────────┘└─
575    by_cases h : a ∈ f.support,
id                    └───────┘
src    └───────┘ └─┘ └───────┘
typ    └───────┘ └─┘└───────┘
doc    └───────┘ └─┘  
txt    └───────┘ └─┘  
par    └───────┘ └─┘  
pid             └─┘  
st   ───────────────────────────┘└─
576    { have : (finset.singleton a : finset α) ⊆ f.support,
id               └──────────────┘    └────┘    └───────┘
src      └─────┘ └──────────────┘ └─┘└────┘ └┘└───────┘
typ      └─────┘ └──────────────┘└─┘└────┘└┘└───────┘
doc      └─────┘ └──────────────┘ └─┘└────┘ └┘ 
txt      └─────┘                  └─┘       └┘ 
par      └─────┘                  └─┘       └┘ 
pid      └───┘└┘                  └─┘       └┘ 
st   ───┘└────────────────────────────────────────────────┘└─
577        { simpa only [finset.subset_iff, mem_singleton, forall_eq] },
id                       └───────────────┘  └───────────┘  └───────┘
src          └──────────┘└───────────────┘└┘└───────────┘└┘└───────┘└┘
typ          └──────────┘└───────────────┘└┘└───────────┘└┘└───────┘└┘
doc          └──────────┘                 └┘             └┘         └┘
txt          └──────────┘                 └┘             └┘         └┘
par          └──────────┘                 └┘             └┘         └┘
pid               └──┘└┘                 └┘             └┘         
st   ───────┘└───────────────────────────────────────────────────────┘└┘
578      refine (finset.sum_subset this (λ _ _ H, _)).symm,
id               └───────────────┘ └──┘
src      └─────┘ └───────────────┘      └──────────────┘
typ      └─────┘ └───────────────┘└──┘  └──────────────┘
doc      └─────┘                        └──────────────┘
txt      └─────┘                        └──────────────┘
par      └─────┘                        └──────────────┘
pid                                    └─────────────┘
st   ────────────────────────────────────────────────────┘└─
579      exact if_neg (mt mem_singleton.2 H) },
id             └────┘  └┘ └───────────┘   
src      └────┘└────┘ └┘└───────────┘└─┘ └┘
typ      └────┘└────┘ └┘└───────────┘└─┘└┘
doc      └────┘                      └─┘ └┘
txt      └────┘                      └─┘ └┘
par      └────┘                      └─┘ └┘
pid                                 └─┘ 
st   ───────────────────────────────────────┘└┘
580    { transitivity (f.support.sum (λa, (0 : β))),
id                     └───────────┘           
src      └───────────┘ └───────────┘  └─┘ └──┘ └─┘
typ      └───────────┘ └───────────┘  └─┘ └──┘└─┘
doc      └───────────┘                └─┘ └──┘ └─┘
txt      └───────────┘                └─┘ └──┘ └─┘
par      └───────────┘                └─┘ └──┘ └─┘
pid                                  └─┘ └──┘ └─┘
st   ─────────────────────────────────────────────┘└─
581      { refine (finset.sum_congr rfl $ λ a' ha', if_neg _),
id                 └──────────────┘ └─┘             └────┘
src        └─────┘ └──────────────┘└─┘  └───────┘└────┘└─┘
typ        └─────┘ └──────────────┘└─┘  └───────┘└────┘└─┘
doc        └─────┘                      └───────┘      └─┘
txt        └─────┘                      └───────┘      └─┘
par        └─────┘                      └───────┘      └─┘
pid                                    └───────┘      └─┘
st   ─────┘└────────────────────────────────────────────────┘└─
582        rintro rfl, exact h ha' },
id                            └─┘
src        └────────┘  └────┘    
typ        └────────┘  └────┘└─┘
doc        └────────┘  └────┘    
txt        └────────┘  └────┘    
par        └────────┘  └────┘    
pid              └──┘           
st   ───────────────┘└────────────┘└┘
583      { rw [sum_const_zero, insert_empty_eq_singleton, sum_singleton,
id             └────────────┘  └───────────────────────┘  └───────────┘
src        └──┘└────────────┘└┘└───────────────────────┘└┘└───────────┘└─
typ        └──┘└────────────┘└┘└───────────────────────┘└┘└───────────┘└─
doc        └──┘              └┘                         └┘             └─
txt        └──┘              └┘                         └┘             └─
par        └──┘              └┘                         └┘             └─
pid          └┘              └┘                         └┘             └─
st   ───────────────────────┘└─────────────────────────┘└─────────────┘└─
584          if_pos rfl, not_mem_support_iff.1 h] } }
id           └────┘ └─┘  └─────────────────┘   
src  ───────┘└────┘└─┘└┘└─────────────────┘└─┘ └┘
typ  ───────┘└────┘└─┘└┘└─────────────────┘└─┘└┘
doc  ───────┘         └┘                   └─┘ └┘
txt  ───────┘         └┘                   └─┘ └┘
par  ───────┘         └┘                   └─┘ └┘
pid  ───────┘         └┘                   └─┘ 
st   ─────────────────┘└───────────────────────┘└───
585  end,
st   ──┘
586  ext $ assume a, by simp only [sum_apply, single_apply, this,
id   └─┘                          └───────┘  └──────────┘  └──┘
src  └─┘                └─────────┘└───────┘└┘└──────────┘└┘    └─
typ  └─┘               └─────────┘└───────┘└┘└──────────┘└┘└──┘└─
doc                     └─────────┘         └┘            └┘    └─
txt                     └─────────┘         └┘            └┘    └─
par                     └─────────┘         └┘            └┘    └─
pid                         └──┘└┘         └┘            └┘    └─
st                     └──────────────────────────────────────────
587    insert_empty_eq_singleton, sum_singleton, if_pos]
id     └───────────────────────┘  └───────────┘  └────┘
src  ─┘└───────────────────────┘└┘└───────────┘└┘└────┘└─
typ  ─┘└───────────────────────┘└┘└───────────┘└┘└────┘└─
doc  ─┘                         └┘             └┘      └─
txt  ─┘                         └┘             └┘      └─
par  ─┘                         └┘             └┘      └─
pid  ─┘                         └┘             └┘      
st   ────────────────────────────────────────────────────
588  
src  
typ  
doc  
txt  
par  
pid  
st   
589  @[to_additive]
doc    └─────────┘
590  lemma prod_add_index [add_comm_monoid β] [comm_monoid γ] {f g : α →₀ β}
id                         └─────────────┘    └─────────┘           └┘ 
src                        └─────────────┘     └─────────┘             └┘
typ                        └─────────────┘    └─────────┘           └┘ 
doc                                                                    └┘
591    {h : α → β → γ} (h_zero : ∀a, h a 0 = 1) (h_add : ∀a b₁ b₂, h a (b₁ + b₂) = h a b₁ * h a b₂) :
id                                                  └┘ └┘     └┘  └┘     └┘    └┘
src                                                                                    
typ                                                 └┘ └┘     └┘  └┘     └┘    └┘
592    (f + g).prod h = f.prod h * g.prod h :=
id         └──┘    └───┘   └───┘ 
src          └──┘      └───┘     └───┘
typ        └──┘    └───┘   └───┘ 
doc           └──┘       └───┘      └───┘
593  have f_eq : (f.support ∪ g.support).prod (λa, h a (f a)) = f.prod h,
id                └──────┘  └──────┘ └──┘              └───┘ 
src                └──────┘   └──────┘ └──┘                    └───┘
typ               └──────┘  └──────┘ └──┘              └───┘ 
doc                                     └──┘                     └───┘
594    from (finset.prod_subset (finset.subset_union_left _ _) $
id           └────────────────┘  └──────────────────────┘
src          └────────────────┘  └──────────────────────┘
typ          └────────────────┘  └──────────────────────┘
595      by intros _ _ H; rw [not_mem_support_iff.1 H, h_zero]).symm,
id                            └─────────────────┘     └────┘  └──┘
src         └──────────┘  └──┘└─────────────────┘└─┘ └┘       └──┘
typ         └──────────┘  └──┘└─────────────────┘└─┘└┘└────┘ └──┘
doc         └──────────┘  └──┘                   └─┘ └┘      
txt         └──────────┘  └──┘                   └─┘ └┘      
par         └──────────┘  └──┘                   └─┘ └┘      
pid               └────┘    └┘                   └─┘ └┘      
st         └─────────────────┘└─────────────────────┘└──────┘
596  have g_eq : (f.support ∪ g.support).prod (λa, h a (g a)) = g.prod h,
id                └──────┘  └──────┘ └──┘              └───┘ 
src                └──────┘   └──────┘ └──┘                    └───┘
typ               └──────┘  └──────┘ └──┘              └───┘ 
doc                                     └──┘                     └───┘
597    from (finset.prod_subset (finset.subset_union_right _ _) $
id           └────────────────┘  └───────────────────────┘
src          └────────────────┘  └───────────────────────┘
typ          └────────────────┘  └───────────────────────┘
598      by intros _ _ H; rw [not_mem_support_iff.1 H, h_zero]).symm,
id                            └─────────────────┘     └────┘  └──┘
src         └──────────┘  └──┘└─────────────────┘└─┘ └┘       └──┘
typ         └──────────┘  └──┘└─────────────────┘└─┘└┘└────┘ └──┘
doc         └──────────┘  └──┘                   └─┘ └┘      
txt         └──────────┘  └──┘                   └─┘ └┘      
par         └──────────┘  └──┘                   └─┘ └┘      
pid               └────┘    └┘                   └─┘ └┘      
st         └─────────────────┘└─────────────────────┘└──────┘
599  calc (f + g).support.prod (λa, h a ((f + g) a)) =
id            └─────┘ └──┘              
src             └─────┘ └──┘               
typ           └─────┘ └──┘              
doc                      └──┘
600        (f.support ∪ g.support).prod (λa, h a ((f + g) a)) :
id          └──────┘  └──────┘ └──┘              
src          └──────┘   └──────┘ └──┘               
typ         └──────┘  └──────┘ └──┘              
doc                               └──┘
601      finset.prod_subset support_add $
id       └────────────────┘ └─────────┘
src      └────────────────┘ └─────────┘
typ      └────────────────┘ └─────────┘
602        by intros _ _ H; rw [not_mem_support_iff.1 H, h_zero]
id                              └─────────────────┘     └────┘
src           └──────────┘  └──┘└─────────────────┘└─┘ └┘      └─
typ           └──────────┘  └──┘└─────────────────┘└─┘└┘└────┘└─
doc           └──────────┘  └──┘                   └─┘ └┘      └─
txt           └──────────┘  └──┘                   └─┘ └┘      └─
par           └──────────┘  └──┘                   └─┘ └┘      └─
pid                 └────┘    └┘                   └─┘ └┘      
st           └─────────────────┘└─────────────────────┘└──────┘
603    ... = (f.support ∪ g.support).prod (λa, h a (f a)) *
id            └──────┘  └──────┘ └──┘             
src  ─┘        └──────┘   └──────┘ └──┘                  
typ  ─┘       └──────┘  └──────┘ └──┘             
doc  ─┘                             └──┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘
604        (f.support ∪ g.support).prod (λa, h a (g a)) :
id          └──────┘  └──────┘ └──┘          
src          └──────┘   └──────┘ └──┘
typ         └──────┘  └──────┘ └──┘          
doc                               └──┘
605      by simp only [add_apply, h_add, finset.prod_mul_distrib]
id                     └───────┘  └───┘  └─────────────────────┘
src         └─────────┘└───────┘└┘     └┘└─────────────────────┘└─
typ         └─────────┘└───────┘└┘└───┘└┘└─────────────────────┘└─
doc         └─────────┘         └┘     └┘                       └─
txt         └─────────┘         └┘     └┘                       └─
par         └─────────┘         └┘     └┘                       └─
pid             └──┘└┘         └┘     └┘                       
st         └──────────────────────────────────────────────────────
606    ... = _ : by rw [f_eq, g_eq]
id                      └──┘  └──┘
src  ─┘             └──┘    └┘    └─
typ  ─┘             └──┘└──┘└┘└──┘└─
doc  ─┘             └──┘    └┘    └─
txt  ─┘             └──┘    └┘    └─
par  ─┘             └──┘    └┘    └─
pid  ─┘               └┘    └┘    
st   ─┘            └───────┘└────┘
607  
src  
typ  
doc  
txt  
par  
pid  
st   
608  lemma sum_sub_index [add_comm_group β] [add_comm_group γ] {f g : α →₀ β}
id                        └────────────┘    └────────────┘           └┘ 
src                       └────────────┘     └────────────┘             └┘
typ                       └────────────┘    └────────────┘           └┘ 
doc                                                                     └┘
609    {h : α → β → γ} (h_sub : ∀a b₁ b₂, h a (b₁ - b₂) = h a b₁ - h a b₂) :
id                             └┘ └┘     └┘  └┘     └┘    └┘
src                                                            
typ                            └┘ └┘     └┘  └┘     └┘    └┘
610    (f - g).sum h = f.sum h - g.sum h :=
id         └─┘    └──┘   └──┘ 
src          └─┘      └──┘     └──┘
typ        └─┘    └──┘   └──┘ 
doc           └─┘       └──┘      └──┘
611  have h_zero : ∀a, h a 0 = 0,
id                        
src                          
typ                       
612    from assume a,
id                 
typ                
613    have h a (0 - 0) = h a 0 - h a 0, from h_sub a 0 0,
id                                   └───┘ 
src                           
typ                                  └───┘ 
614    by simpa only [sub_self] using this,
id                    └──────┘        └──┘
src       └──────────┘└──────┘└──────┘
typ       └──────────┘└──────┘└──────┘└──┘
doc       └──────────┘        └──────┘
txt       └──────────┘        └──────┘
par       └──────────┘        └──────┘
pid            └──┘└┘        └────┘
st       └───────────────────────────────┘
615  have h_neg : ∀a b, h a (- b) = - h a b,
id                              
src                               
typ                             
616    from assume a b,
id                  
typ                 
617    have h a (0 - b) = h a 0 - h a b, from h_sub a 0 b,
id                                 └───┘    
src                           
typ                                └───┘    
618    by simpa only [h_zero, zero_sub] using this,
id                    └────┘  └──────┘        └──┘
src       └──────────┘      └┘└──────┘└──────┘
typ       └──────────┘└────┘└┘└──────┘└──────┘└──┘
doc       └──────────┘      └┘        └──────┘
txt       └──────────┘      └┘        └──────┘
par       └──────────┘      └┘        └──────┘
pid            └──┘└┘      └┘        └────┘
st       └───────────────────────────────────────┘
619  have h_add : ∀a b₁ b₂, h a (b₁ + b₂) = h a b₁ + h a b₂,
id                  └┘ └┘     └┘  └┘     └┘    └┘
src                                              
typ                 └┘ └┘     └┘  └┘     └┘    └┘
620    from assume a b₁ b₂,
id                  └┘ └┘
typ                 └┘ └┘
621    have h a (b₁ - (- b₂)) = h a b₁ - h a (- b₂), from h_sub a b₁ (-b₂),
id             └┘    └┘      └┘      └┘        └───┘  └┘  └┘
src                                                              
typ            └┘    └┘      └┘      └┘        └───┘  └┘  └┘
622    by simpa only [h_neg, sub_neg_eq_add] using this,
id                    └───┘  └────────────┘        └──┘
src       └──────────┘     └┘└────────────┘└──────┘
typ       └──────────┘└───┘└┘└────────────┘└──────┘└──┘
doc       └──────────┘     └┘              └──────┘
txt       └──────────┘     └┘              └──────┘
par       └──────────┘     └┘              └──────┘
pid            └──┘└┘     └┘              └────┘
st       └────────────────────────────────────────────┘
623  calc (f - g).sum h = (f + - g).sum h : rfl
id            └─┘          └─┘     └─┘
src             └─┘             └─┘      └─┘
typ           └─┘          └─┘     └─┘
doc              └─┘               └─┘
624    ... = f.sum h + - g.sum h : by simp only [sum_add_index h_zero h_add, sum_neg_index h_zero, h_neg, sum_neg]
id           └──┘    └──┘                  └───────────┘ └────┘ └───┘  └───────────┘ └────┘  └───┘  └─────┘
src           └──┘      └──┘        └─────────┘└───────────┘           └┘└───────────┘      └┘     └┘└─────┘└─
typ          └──┘    └──┘       └─────────┘└───────────┘└────┘└───┘└┘└───────────┘└────┘└┘└───┘└┘└─────┘└─
doc           └──┘        └──┘        └─────────┘                        └┘                   └┘     └┘       └─
txt                                   └─────────┘                        └┘                   └┘     └┘       └─
par                                   └─────────┘                        └┘                   └┘     └┘       └─
pid                                       └──┘└┘                        └┘                   └┘     └┘       
st                                   └─────────────────────────────────────────────────────────────────────────────
625    ... = f.sum h - g.sum h : rfl
id           └──┘   └──┘    └─┘
src  ─┘       └──┘     └──┘     └─┘
typ  ─┘      └──┘   └──┘    └─┘
doc  ─┘       └──┘      └──┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘
626  
627  @[to_additive]
doc    └─────────┘
628  lemma prod_finset_sum_index [add_comm_monoid β] [comm_monoid γ]
id                                └─────────────┘    └─────────┘ 
src                               └─────────────┘     └─────────┘
typ                               └─────────────┘    └─────────┘ 
629    {s : finset ι} {g : ι → α →₀ β}
id          └────┘            └┘ 
src         └────┘               └┘
typ         └────┘            └┘ 
doc         └────┘               └┘
630    {h : α → β → γ} (h_zero : ∀a, h a 0 = 1) (h_add : ∀a b₁ b₂, h a (b₁ + b₂) = h a b₁ * h a b₂) :
id                                                  └┘ └┘     └┘  └┘     └┘    └┘
src                                                                                    
typ                                                 └┘ └┘     └┘  └┘     └┘    └┘
631    s.prod (λi, (g i).prod h) = (s.sum g).prod h :=
id     └───┘        └──┘      └──┘  └──┘  
src     └───┘           └──┘        └──┘   └──┘
typ    └───┘        └──┘      └──┘  └──┘  
doc     └───┘           └──┘                └──┘
632  finset.induction_on s rfl $ λ a s has ih,
id   └─────────────────┘  └─┘       └─┘ └┘
src  └─────────────────┘   └─┘
typ  └─────────────────┘  └─┘       └─┘ └┘
doc  └─────────────────┘
633  by rw [prod_insert has, ih, sum_insert has, prod_add_index h_zero h_add]
id          └─────────┘ └─┘  └┘  └────────┘ └─┘  └────────────┘ └────┘ └───┘
src     └──┘└─────────┘   └┘  └┘└────────┘   └┘└────────────┘           └─
typ     └──┘└─────────┘└─┘└┘└┘└┘└────────┘└─┘└┘└────────────┘└────┘└───┘└─
doc     └──┘              └┘  └┘             └┘                         └─
txt     └──┘              └┘  └┘             └┘                         └─
par     └──┘              └┘  └┘             └┘                         └─
pid       └┘              └┘  └┘             └┘                         
st     └──────────────────┘└──┘└──────────────┘└───────────────────────────┘
634  
src  
typ  
doc  
txt  
par  
pid  
st   
635  @[to_additive]
doc    └─────────┘
636  lemma prod_sum_index
637    [add_comm_monoid β₁] [add_comm_monoid β] [comm_monoid γ]
id      └─────────────┘ └┘   └─────────────┘    └─────────┘ 
src     └─────────────┘      └─────────────┘     └─────────┘
typ     └─────────────┘ └┘   └─────────────┘    └─────────┘ 
638    {f : α₁ →₀ β₁} {g : α₁ → β₁ → α →₀ β}
id          └┘ └┘ └┘       └┘   └┘    └┘ 
src            └┘                      └┘
typ         └┘ └┘ └┘       └┘   └┘    └┘ 
doc            └┘                      └┘
639    {h : α → β → γ} (h_zero : ∀a, h a 0 = 1) (h_add : ∀a b₁ b₂, h a (b₁ + b₂) = h a b₁ * h a b₂) :
id                                                  └┘ └┘     └┘  └┘     └┘    └┘
src                                                                                    
typ                                                 └┘ └┘     └┘  └┘     └┘    └┘
640    (f.sum g).prod h = f.prod (λa b, (g a b).prod h) :=
id      └──┘  └──┘    └───┘          └──┘  
src      └──┘   └──┘      └───┘               └──┘
typ     └──┘  └──┘    └───┘          └──┘  
doc      └──┘   └──┘       └───┘               └──┘
641  (prod_finset_sum_index h_zero h_add).symm
id    └───────────────────┘ └────┘ └───┘ └──┘
src   └───────────────────┘              └──┘
typ   └───────────────────┘ └────┘ └───┘ └──┘
642  
643  lemma multiset_sum_sum_index
644    [add_comm_monoid β] [add_comm_monoid γ]
id      └─────────────┘    └─────────────┘ 
src     └─────────────┘     └─────────────┘
typ     └─────────────┘    └─────────────┘ 
645    (f : multiset (α →₀ β)) (h : α → β → γ)
id          └──────┘   └┘               
src         └──────┘    └┘
typ         └──────┘   └┘               
doc         └──────┘    └┘
646    (h₀ : ∀a, h a 0 = 0) (h₁ : ∀ (a : α) (b₁ b₂ : β), h a (b₁ + b₂) = h a b₁ + h a b₂) :
id                                                    └┘  └┘     └┘    └┘
src                                                                          
typ                                                   └┘  └┘     └┘    └┘
647    (f.sum.sum h) = (f.map $ λg:α →₀ β, g.sum h).sum :=
id      └──┘└──┘     └──┘       └┘   └──┘  └─┘
src      └──┘└──┘       └──┘        └┘     └──┘   └─┘
typ     └──┘└──┘     └──┘       └┘   └──┘  └─┘
doc          └──┘        └──┘        └┘     └──┘
648  multiset.induction_on f rfl $ assume a s ih,
id   └───────────────────┘  └─┘            └┘
src  └───────────────────┘   └─┘
typ  └───────────────────┘  └─┘            └┘
649  by rw [multiset.sum_cons, multiset.map_cons, multiset.sum_cons, sum_add_index h₀ h₁, ih]
id          └───────────────┘  └───────────────┘  └───────────────┘  └───────────┘ └┘ └┘  └┘
src     └──┘└───────────────┘└┘└───────────────┘└┘└───────────────┘└┘└───────────┘    └┘  └─
typ     └──┘└───────────────┘└┘└───────────────┘└┘└───────────────┘└┘└───────────┘└┘└┘└┘└┘└─
doc     └──┘                 └┘                 └┘                 └┘                 └┘  └─
txt     └──┘                 └┘                 └┘                 └┘                 └┘  └─
par     └──┘                 └┘                 └┘                 └┘                 └┘  └─
pid       └┘                 └┘                 └┘                 └┘                 └┘  
st     └────────────────────┘└─────────────────┘└─────────────────┘└───────────────────┘└──┘
650  
src  
typ  
doc  
txt  
par  
pid  
st   
651  lemma multiset_map_sum [has_zero β] {f : α →₀ β} {m : γ → δ} {h : α → β → multiset γ} :
id                           └──────┘         └┘                        └──────┘ 
src                          └──────┘           └┘                             └──────┘
typ                          └──────┘         └┘                        └──────┘ 
doc                                             └┘                             └──────┘
652    multiset.map m (f.sum h) = f.sum (λa b, (h a b).map m) :=
id     └──────────┘   └──┘    └──┘          └─┘  
src    └──────────┘     └──┘      └──┘               └─┘
typ    └──────────┘   └──┘    └──┘          └─┘  
doc    └──────────┘     └──┘       └──┘               └─┘
653  (f.support.sum_hom _).symm
id    └──────┘└──────┘   └──┘
src    └──────┘└──────┘   └──┘
typ   └──────┘└──────┘   └──┘
654  
655  lemma multiset_sum_sum [has_zero β] [add_comm_monoid γ] {f : α →₀ β} {h : α → β → multiset γ} :
id                           └──────┘    └─────────────┘         └┘              └──────┘ 
src                          └──────┘     └─────────────┘           └┘                 └──────┘
typ                          └──────┘    └─────────────┘         └┘              └──────┘ 
doc                                                                 └┘                 └──────┘
656    multiset.sum (f.sum h) = f.sum (λa b, multiset.sum (h a b)) :=
id     └──────────┘  └──┘    └──┘      └──────────┘    
src    └──────────┘   └──┘      └──┘        └──────────┘
typ    └──────────┘  └──┘    └──┘      └──────────┘    
doc                   └──┘       └──┘
657  (f.support.sum_hom multiset.sum).symm
id    └──────┘└──────┘ └──────────┘ └──┘
src    └──────┘└──────┘ └──────────┘ └──┘
typ   └──────┘└──────┘ └──────────┘ └──┘
658  
659  section map_range
660  variables
661    [add_comm_monoid β₁] [add_comm_monoid β₂]
id      └─────────────┘      └─────────────┘
src     └─────────────┘      └─────────────┘
typ     └─────────────┘      └─────────────┘
662    (f : β₁ → β₂) [hf : is_add_monoid_hom f]
id                         └───────────────┘
src                        └───────────────┘
typ                        └───────────────┘
doc                        └───────────────┘
663  
664  instance is_add_monoid_hom_map_range :
665    is_add_monoid_hom (map_range f hf.map_zero : (α →₀ β₁) → (α →₀ β₂)) :=
id     └───────────────┘  └───────┘  └┘└───────┘     └┘ └┘      └┘ └┘
src    └───────────────┘  └───────┘     └───────┘      └┘          └┘
typ    └───────────────┘  └───────┘  └┘└───────┘     └┘ └┘      └┘ └┘
doc    └───────────────┘  └───────┘                    └┘          └┘
666  { map_zero := map_range_zero, map_add := λ a b, map_range_add hf.map_add _ _ }
id                 └────────────┘                  └───────────┘ └┘└──────┘
src                └────────────┘                    └───────────┘   └──────┘
typ                └────────────┘                  └───────────┘ └┘└──────┘
667  
668  lemma map_range_multiset_sum (m : multiset (α →₀ β₁)) :
id                                     └──────┘   └┘ └┘
src                                    └──────┘    └┘
typ                                    └──────┘   └┘ └┘
doc                                    └──────┘    └┘
669    map_range f hf.map_zero m.sum = (m.map $ λx, map_range f hf.map_zero x).sum :=
id     └───────┘  └┘└───────┘ └──┘   └──┘      └───────┘  └┘└───────┘  └─┘
src    └───────┘     └───────┘  └──┘    └──┘       └───────┘     └───────┘   └─┘
typ    └───────┘  └┘└───────┘ └──┘   └──┘      └───────┘  └┘└───────┘  └─┘
doc    └───────┘                         └──┘       └───────┘
670  (m.sum_hom (map_range f hf.map_zero)).symm
id    └──────┘  └───────┘  └┘└───────┘  └──┘
src    └──────┘  └───────┘     └───────┘  └──┘
typ   └──────┘  └───────┘  └┘└───────┘  └──┘
doc              └───────┘
671  
672  lemma map_range_finset_sum {ι : Type*} (s : finset ι) (g : ι → (α →₀ β₁))  :
id                                               └────┘             └┘ └┘
src                                              └────┘                └┘
typ                                              └────┘             └┘ └┘
doc                                              └────┘                └┘
673    map_range f hf.map_zero (s.sum g) = s.sum (λx, map_range f hf.map_zero (g x)) :=
id     └───────┘  └┘└───────┘  └──┘    └──┘     └───────┘  └┘└───────┘   
src    └───────┘     └───────┘   └──┘      └──┘      └───────┘     └───────┘
typ    └───────┘  └┘└───────┘  └──┘    └──┘     └───────┘  └┘└───────┘   
doc    └───────┘                                      └───────┘
674  by rw [finset.sum.equations._eqn_1, map_range_multiset_sum, multiset.map_map]; refl
id          └─────────────────────────┘  └────────────────────┘  └──────────────┘
src     └──┘└─────────────────────────┘└┘└────────────────────┘└┘└──────────────┘  └────
typ     └──┘└─────────────────────────┘└┘└────────────────────┘└┘└──────────────┘  └────
doc     └──┘                           └┘                      └┘                  └────
txt     └──┘                           └┘                      └┘                  └────
par     └──┘                           └┘                      └┘                  └────
pid       └┘                           └┘                      └┘                      
st     └──────────────────────────────┘└──────────────────────┘└────────────────┘└──────
675  
src  
typ  
doc  
txt  
par  
pid  
st   
676  end map_range
677  
678  section map_domain
679  variables [add_comm_monoid β] {v v₁ v₂ : α →₀ β}
id              └─────────────┘                 └┘
src             └─────────────┘                 └┘
typ             └─────────────┘                 └┘
doc                                             └┘
680  
681  /-- Given `f : α₁ → α₂` and `v : α₁ →₀ β`, `map_domain f v : α₂ →₀ β`
682    is the finitely supported function whose value at `a : α₂` is the sum
683    of `v x` over all `x` such that `f x = a`. -/
684  def map_domain (f : α₁ → α₂) (v : α₁ →₀ β) : α₂ →₀ β :=
id                       └┘   └┘       └┘ └┘     └┘ └┘ 
src                                       └┘         └┘
typ                      └┘   └┘       └┘ └┘     └┘ └┘ 
doc                                       └┘         └┘
685  v.sum $ λa, single (f a)
id   └──┘      └────┘   
src   └──┘       └────┘
typ  └──┘      └────┘   
doc   └──┘       └────┘
686  
687  lemma map_domain_apply {f : α₁ → α₂} (hf : function.injective f) (x : α₁ →₀ β) (a : α₁) :
id                               └┘   └┘        └────────────────┘        └┘ └┘        └┘
src                                             └────────────────┘            └┘
typ                              └┘   └┘        └────────────────┘        └┘ └┘        └┘
doc                                                                           └┘
688    map_domain f x (f a) = x a :=
id     └────────┘         
src    └────────┘           
typ    └────────┘         
doc    └────────┘
689  begin
st   └─────
690    rw [map_domain, sum_apply, sum, finset.sum_eq_single a, single_eq_same],
id         └────────┘  └───────┘  └─┘  └──────────────────┘   └────────────┘
src    └──┘└────────┘└┘└───────┘└┘└─┘└┘└──────────────────┘ └┘└────────────┘
typ    └──┘└────────┘└┘└───────┘└┘└─┘└┘└──────────────────┘└┘└────────────┘
doc    └──┘└────────┘└┘         └┘└─┘└┘                     └┘              
txt    └──┘          └┘         └┘   └┘                     └┘              
par    └──┘          └┘         └┘   └┘                     └┘              
pid      └┘          └┘         └┘   └┘                     └┘              
st   ───────────────┘└─────────┘└───┘└──────────────────────┘└──────────────┘└──
691    { assume b _ hba, exact single_eq_of_ne (hf.ne hba) },
id                             └─────────────┘  └───┘ └─┘
src      └────────────┘  └────┘└─────────────┘ └───┘   └┘
typ      └────────────┘  └────┘└─────────────┘ └───┘└─┘└┘
doc      └────────────┘  └────┘                        └┘
txt      └────────────┘  └────┘                        └┘
par      └────────────┘  └────┘                        └┘
pid      └────────────┘                               
st   ───┘└────────────┘└──────────────────────────────────┘└┘
692    { simp only [(∉), (≠), not_not, mem_support_iff],
id                          └─────┘  └─────────────┘
src      └─────────┘└──┘└──┘└─────┘└┘└─────────────┘
typ      └─────────┘└──┘└──┘└─────┘└┘└─────────────┘
doc      └─────────┘ └──┘ └──┘       └┘               
txt      └─────────┘ └──┘ └──┘       └┘               
par      └─────────┘ └──┘ └──┘       └┘               
pid          └──┘└┘ └──┘ └──┘       └┘               
st   ─────────────────────────────────────────────────┘└─
693      assume h,
src      └──────┘
typ      └──────┘
doc      └──────┘
txt      └──────┘
par      └──────┘
pid      └──────┘
st   ───────────┘└─
694      rw [h, single_zero],
id             └─────────┘
src      └──┘ └┘└─────────┘
typ      └──┘└┘└─────────┘
doc      └──┘ └┘           
txt      └──┘ └┘           
par      └──┘ └┘           
pid        └┘ └┘           
st   ────────┘└───────────┘└──
695      refl }
src      └───┘
typ      └───┘
doc      └───┘
txt      └───┘
par      └───┘
pid          
st   ────────┘└─
696  end
st   ──┘
697  
698  lemma map_domain_notin_range {f : α₁ → α₂} (x : α₁ →₀ β) (a : α₂) (h : a ∉ set.range f) :
id                                     └┘   └┘       └┘ └┘        └┘         └───────┘ 
src                                                     └┘                    └───────┘
typ                                    └┘   └┘       └┘ └┘        └┘         └───────┘ 
doc                                                     └┘                      └───────┘
699    map_domain f x a = 0 :=
id     └────────┘    
src    └────────┘       
typ    └────────┘    
doc    └────────┘
700  begin
st   └─────
701    rw [map_domain, sum_apply, sum],
id         └────────┘  └───────┘  └─┘
src    └──┘└────────┘└┘└───────┘└┘└─┘
typ    └──┘└────────┘└┘└───────┘└┘└─┘
doc    └──┘└────────┘└┘         └┘└─┘
txt    └──┘          └┘         └┘   
par    └──┘          └┘         └┘   
pid      └┘          └┘         └┘   
st   ───────────────┘└─────────┘└───┘└──
702    exact finset.sum_eq_zero
id           └────────────────┘
src    └────┘└────────────────┘
typ    └────┘└────────────────┘
doc    └────┘                  
txt    └────┘                  
par    └────┘                  
pid                           
st   ───────────────────────────
703      (assume a' h', single_eq_of_ne $ assume eq, h $ eq ▸ set.mem_range_self _)
id                      └─────────────┘                     └────────────────┘
src  ───┘       └──────┘└─────────────┘       └───┘    └────────────────┘└──┘
typ  ───┘       └──────┘└─────────────┘       └───┘   └────────────────┘└──┘
doc  ───┘       └──────┘                      └───┘                       └──┘
txt  ───┘       └──────┘                      └───┘                       └──┘
par  ───┘       └──────┘                      └───┘                       └──┘
pid  ───┘       └──────┘                      └───┘                       └─┘
st   ──────────────────────────────────────────────────────────────────────────────┘
704  end
st   └─┘
705  
706  lemma map_domain_id : map_domain id v = v := sum_single _
id                         └────────┘ └┘       └────────┘
src                        └────────┘ └┘         └────────┘
typ                        └────────┘ └┘       └────────┘
doc                        └────────┘
707  
708  lemma map_domain_comp {f : α → α₁} {g : α₁ → α₂} :
id                                 └┘       └┘   └┘
typ                                └┘       └┘   └┘
709    map_domain (g ∘ f) v = map_domain g (map_domain f v) :=
id     └────────┘        └────────┘   └────────┘  
src    └────────┘           └────────┘    └────────┘
typ    └────────┘        └────────┘   └────────┘  
doc    └────────┘             └────────┘    └────────┘
710  begin
st   └─────
711    refine ((sum_sum_index _ _).trans _).symm,
id              └───────────┘
src    └─────┘  └───────────┘└─────────────────┘
typ    └─────┘  └───────────┘└─────────────────┘
doc    └─────┘               └─────────────────┘
txt    └─────┘               └─────────────────┘
par    └─────┘               └─────────────────┘
pid                         └────────────────┘
st   ──────────────────────────────────────────┘└─
712    { intros, exact single_zero },
id                     └─────────┘
src      └────┘  └────┘└─────────┘
typ      └────┘  └────┘└─────────┘
doc      └────┘  └────┘           
txt      └────┘  └────┘           
par      └────┘  └────┘           
pid                              
st   ───┘└────┘└──────────────────┘└┘
713    { intros, exact single_add },
id                     └────────┘
src      └────┘  └────┘└────────┘
typ      └────┘  └────┘└────────┘
doc      └────┘  └────┘          
txt      └────┘  └────┘          
par      └────┘  └────┘          
pid                             
st   ───┘└────┘└─────────────────┘└┘
714    refine sum_congr rfl (λ _ _, sum_single_index _),
id            └───────┘ └─┘         └──────────────┘
src    └─────┘└───────┘└─┘  └────┘└──────────────┘└─┘
typ    └─────┘└───────┘└─┘  └────┘└──────────────┘└─┘
doc    └─────┘              └────┘                └─┘
txt    └─────┘              └────┘                └─┘
par    └─────┘              └────┘                └─┘
pid                        └────┘                └─┘
st   ─────────────────────────────────────────────────┘└─
715    { exact single_zero }
id             └─────────┘
src      └────┘└─────────┘
typ      └────┘└─────────┘
doc      └────┘           
txt      └────┘           
par      └────┘           
pid                      
st   ─────────────────────┘└─
716  end
st   ──┘
717  
718  lemma map_domain_single {f : α → α₁} {a : α} {b : β} : map_domain f (single a b) = single (f a) b :=
id                                   └┘                  └────────┘   └────┘     └────┘     
src                                                         └────────┘    └────┘       └────┘
typ                                  └┘                  └────────┘   └────┘     └────┘     
doc                                                         └────────┘    └────┘        └────┘
719  sum_single_index single_zero
id   └──────────────┘ └─────────┘
src  └──────────────┘ └─────────┘
typ  └──────────────┘ └─────────┘
720  
721  @[simp] lemma map_domain_zero {f : α → α₂} : map_domain f 0 = (0 : α₂ →₀ β) :=
id                                         └┘    └────────┘          └┘ └┘ 
src                                               └────────┘              └┘
typ                                        └┘    └────────┘          └┘ └┘ 
doc    └──┘                                       └────────┘               └┘
722  sum_zero_index
id   └────────────┘
src  └────────────┘
typ  └────────────┘
723  
724  lemma map_domain_congr {f g : α → α₂} (h : ∀x∈v.support, f x = g x) :
id                                    └┘         └──────┘      
src                                                 └──────┘      
typ                                   └┘         └──────┘      
725    v.map_domain f = v.map_domain g :=
id     └─────────┘   └─────────┘ 
src     └─────────┘     └─────────┘
typ    └─────────┘   └─────────┘ 
doc     └─────────┘      └─────────┘
726  finset.sum_congr rfl $ λ _ H, by simp only [h _ H]
id   └──────────────┘ └─┘                         
src  └──────────────┘ └─┘             └─────────┘ └─┘ └─
typ  └──────────────┘ └─┘           └─────────┘└─┘└─
doc                                   └─────────┘ └─┘ └─
txt                                   └─────────┘ └─┘ └─
par                                   └─────────┘ └─┘ └─
pid                                       └──┘└┘ └─┘ 
st                                   └──────────────────
727  
src  
typ  
doc  
txt  
par  
pid  
st   
728  lemma map_domain_add {f : α → α₂} : map_domain f (v₁ + v₂) = map_domain f v₁ + map_domain f v₂ :=
id                                └┘    └────────┘   └┘  └┘   └────────┘  └┘  └────────┘  └┘
src                                      └────────┘             └────────┘       └────────┘
typ                               └┘    └────────┘   └┘  └┘   └────────┘  └┘  └────────┘  └┘
doc                                      └────────┘               └────────┘        └────────┘
729  sum_add_index (λ _, single_zero) (λ _ _ _, single_add)
id   └───────────┘      └─────────┘         └────────┘
src  └───────────┘       └─────────┘            └────────┘
typ  └───────────┘      └─────────┘         └────────┘
730  
731  lemma map_domain_finset_sum {f : α → α₂} {s : finset ι} {v : ι → α →₀ β} :
id                                       └┘       └────┘            └┘ 
src                                                └────┘               └┘
typ                                      └┘       └────┘            └┘ 
doc                                                └────┘               └┘
732    map_domain f (s.sum v) = s.sum (λi, map_domain f (v i)) :=
id     └────────┘   └──┘    └──┘     └────────┘    
src    └────────┘     └──┘      └──┘      └────────┘
typ    └────────┘   └──┘    └──┘     └────────┘    
doc    └────────┘                          └────────┘
733  eq.symm $ sum_finset_sum_index (λ _, single_zero) (λ _ _ _, single_add)
id   └─────┘   └──────────────────┘      └─────────┘         └────────┘
src  └─────┘   └──────────────────┘       └─────────┘            └────────┘
typ  └─────┘   └──────────────────┘      └─────────┘         └────────┘
734  
735  lemma map_domain_sum [has_zero β₁] {f : α → α₂} {s : α →₀ β₁} {v : α → β₁ → α →₀ β} :
id                         └──────┘ └┘          └┘        └┘ └┘          └┘    └┘ 
src                        └──────┘                         └┘                     └┘
typ                        └──────┘ └┘          └┘        └┘ └┘          └┘    └┘ 
doc                                                         └┘                     └┘
736    map_domain f (s.sum v) = s.sum (λa b, map_domain f (v a b)) :=
id     └────────┘   └──┘    └──┘      └────────┘     
src    └────────┘     └──┘      └──┘        └────────┘
typ    └────────┘   └──┘    └──┘      └────────┘     
doc    └────────┘     └──┘       └──┘        └────────┘
737  eq.symm $ sum_finset_sum_index (λ _, single_zero) (λ _ _ _, single_add)
id   └─────┘   └──────────────────┘      └─────────┘         └────────┘
src  └─────┘   └──────────────────┘       └─────────┘            └────────┘
typ  └─────┘   └──────────────────┘      └─────────┘         └────────┘
738  
739  lemma map_domain_support {f : α → α₂} {s : α →₀ β} :
id                                    └┘        └┘ 
src                                               └┘
typ                                   └┘        └┘ 
doc                                               └┘
740    (s.map_domain f).support ⊆ s.support.image f :=
id      └─────────┘  └─────┘   └──────┘└────┘ 
src      └─────────┘   └─────┘    └──────┘└────┘
typ     └─────────┘  └─────┘   └──────┘└────┘ 
doc      └─────────┘                       └────┘
741  finset.subset.trans support_sum $
id   └─────────────────┘ └─────────┘
src  └─────────────────┘ └─────────┘
typ  └─────────────────┘ └─────────┘
742    finset.subset.trans (finset.bind_mono $ assume a ha, support_single_subset) $
id     └─────────────────┘  └──────────────┘           └┘  └───────────────────┘
src    └─────────────────┘  └──────────────┘                └───────────────────┘
typ    └─────────────────┘  └──────────────┘           └┘  └───────────────────┘
743    by rw [finset.bind_singleton]; exact subset.refl _
id            └───────────────────┘         └─────────┘
src       └──┘└───────────────────┘  └────┘└─────────┘└──
typ       └──┘└───────────────────┘  └────┘└─────────┘└──
doc       └──┘                       └────┘           └──
txt       └──┘                       └────┘           └──
par       └──┘                       └────┘           └──
pid         └┘                                       └┘
st       └────────────────────────┘└─────────────────────
744  
src  
typ  
doc  
txt  
par  
pid  
st   
745  @[to_additive]
doc    └─────────┘
746  lemma prod_map_domain_index [comm_monoid γ] {f : α → α₂} {s : α →₀ β}
id                                └─────────┘           └┘        └┘ 
src                               └─────────┘                        └┘
typ                               └─────────┘           └┘        └┘ 
doc                                                                  └┘
747    {h : α₂ → β → γ} (h_zero : ∀a, h a 0 = 1) (h_add : ∀a b₁ b₂, h a (b₁ + b₂) = h a b₁ * h a b₂) :
id          └┘                                        └┘ └┘     └┘  └┘     └┘    └┘
src                                                                                     
typ         └┘                                        └┘ └┘     └┘  └┘     └┘    └┘
748    (s.map_domain f).prod h = s.prod (λa b, h (f a) b) :=
id      └─────────┘  └──┘    └───┘           
src      └─────────┘   └──┘      └───┘
typ     └─────────┘  └──┘    └───┘           
doc      └─────────┘   └──┘       └───┘
749  (prod_sum_index h_zero h_add).trans $ prod_congr rfl $ λ _ _, prod_single_index (h_zero _)
id    └────────────┘ └────┘ └───┘ └───┘    └────────┘ └─┘        └───────────────┘  └────┘
src   └────────────┘              └───┘    └────────┘ └─┘          └───────────────┘
typ   └────────────┘ └────┘ └───┘ └───┘    └────────┘ └─┘        └───────────────┘  └────┘
750  
751  lemma emb_domain_eq_map_domain (f : α₁ ↪ α₂) (v : α₁ →₀ β) :
id                                       └┘  └┘       └┘ └┘ 
src                                                      └┘
typ                                      └┘  └┘       └┘ └┘ 
doc                                                       └┘
752    emb_domain f v = map_domain f v :=
id     └────────┘    └────────┘  
src    └────────┘      └────────┘
typ    └────────┘    └────────┘  
doc    └────────┘       └────────┘
753  begin
st   └─────
754    ext a,
src    └───┘
typ    └───┘
doc    └───┘
txt    └───┘
par    └───┘
pid       └┘
st   ──────┘└─
755    by_cases a ∈ set.range f,
id                └───────┘ 
src    └───────┘ └───────┘
typ    └───────┘└───────┘
doc    └───────┘  └───────┘
txt    └───────┘           
par    └───────┘           
pid                       
st   ─────────────────────────┘└─
756    { rcases h with ⟨a, rfl⟩,
id              
src      └─────┘ └────────────┘
typ      └─────┘└────────────┘
doc      └─────┘ └────────────┘
txt      └─────┘ └────────────┘
par      └─────┘ └────────────┘
pid             └────────────┘
st   ───┘└────────────────────┘└─
757      rw [map_domain_apply (function.embedding.inj' _), emb_domain_apply] },
id           └──────────────┘  └─────────────────────┘     └──────────────┘
src      └──┘└──────────────┘ └─────────────────────┘└───┘└──────────────┘└┘
typ      └──┘└──────────────┘ └─────────────────────┘└───┘└──────────────┘└┘
doc      └──┘                                        └───┘                └┘
txt      └──┘                                        └───┘                └┘
par      └──┘                                        └───┘                └┘
pid        └┘                                        └───┘                
st   ───────────────────────────────────────────────────┘└────────────────┘└┘
758    { rw [map_domain_notin_range, emb_domain_notin_range]; assumption }
id           └────────────────────┘  └────────────────────┘
src      └──┘└────────────────────┘└┘└────────────────────┘  └─────────┘
typ      └──┘└────────────────────┘└┘└────────────────────┘  └─────────┘
doc      └──┘                      └┘                        └─────────┘
txt      └──┘                      └┘                        └─────────┘
par      └──┘                      └┘                        └─────────┘
pid        └┘                      └┘                                  
st   ─────────────────────────────┘└──────────────────────┘└───────────┘└─
759  end
st   ──┘
760  
761  lemma injective_map_domain {f : α₁ → α₂} (hf : function.injective f) :
id                                   └┘   └┘        └────────────────┘ 
src                                                 └────────────────┘
typ                                  └┘   └┘        └────────────────┘ 
762    function.injective (map_domain f : (α₁ →₀ β) → (α₂ →₀ β)) :=
id     └────────────────┘  └────────┘     └┘ └┘      └┘ └┘ 
src    └────────────────┘  └────────┘         └┘          └┘
typ    └────────────────┘  └────────┘     └┘ └┘      └┘ └┘ 
doc                        └────────┘         └┘          └┘
763  begin
st   └─────
764    assume v₁ v₂ eq, ext a,
src    └─────────────┘  └───┘
typ    └─────────────┘  └───┘
doc    └─────────────┘  └───┘
txt    └─────────────┘  └───┘
par    └─────────────┘  └───┘
pid    └─────────────┘     └┘
st   ────────────────┘└─────┘└─
765    have : map_domain f v₁ (f a) = map_domain f v₂ (f a), { rw eq },
id                         └┘        └────────┘   └┘           └┘
src    └─────┘                └┘└────────┘          └─┘└┘
typ    └─────┘           └┘   └┘└────────┘ └┘     └─┘└┘
doc    └─────┘                └┘ └────────┘          └─┘  
txt    └─────┘                └┘                     └─┘  
par    └─────┘                └┘                     └─┘  
pid    └───┘└┘                └┘                         
st   ─────────────────────────────────────────────────────┘└──┘└────┘└┘
766    rwa [map_domain_apply hf, map_domain_apply hf] at this,
id          └──────────────┘ └┘  └──────────────┘ └┘
src    └───┘└──────────────┘  └┘└──────────────┘  └───────┘
typ    └───┘└──────────────┘└┘└┘└──────────────┘└┘└───────┘
doc    └───┘                  └┘                  └───────┘
txt    └───┘                  └┘                  └───────┘
par    └───┘                  └┘                  └───────┘
pid       └┘                  └┘                  └──────┘
st   ─────────────────────────┘└───────────────────┘└──────┘└─
767  end
st   ──┘
768  
769  end map_domain
770  
771  section comap_domain
772  
773  noncomputable def comap_domain {α₁ α₂ γ : Type*} [has_zero γ]
id                                                     └──────┘ 
src                                                    └──────┘
typ                                                    └──────┘ 
774    (f : α₁ → α₂) (l : α₂ →₀ γ) (hf : set.inj_on f (f ⁻¹' l.support.to_set)) : α₁ →₀ γ :=
id          └┘   └┘       └┘ └┘         └────────┘    └─┘ └──────┘└─────┘     └┘ └┘ 
src                          └┘          └────────┘      └─┘  └──────┘└─────┘        └┘
typ         └┘   └┘       └┘ └┘         └────────┘    └─┘ └──────┘└─────┘     └┘ └┘ 
doc                          └┘          └────────┘      └─┘          └─────┘        └┘
775  { support := l.support.preimage hf,
id                └──────┘└───────┘ └┘
src                └──────┘└───────┘
typ               └──────┘└───────┘ └┘
776    to_fun := (λ a, l (f a)),
id                       
typ                      
777    mem_support_to_fun :=
778      begin
st       └─────
779        intros a,
src        └──────┘
typ        └──────┘
doc        └──────┘
txt        └──────┘
par        └──────┘
pid              └┘
st   ─────────────┘└─
780        simp only [finset.mem_def.symm, finset.mem_preimage],
id                                         └─────────────────┘
src        └─────────┘                   └┘└─────────────────┘
typ        └─────────┘└─────────────────┘└┘└─────────────────┘
doc        └─────────┘                   └┘                   
txt        └─────────┘                   └┘                   
par        └─────────┘                   └┘                   
pid            └──┘└┘                   └┘                   
st   ─────────────────────────────────────────────────────────┘└─
781        exact l.mem_support_to_fun (f a),
id               └──────────────────┘   
src        └────┘└──────────────────┘   
typ        └────┘└──────────────────┘ 
doc        └────┘                       
txt        └────┘                       
par        └────┘                       
pid                                    
st   ─────────────────────────────────────┘└─
782      end }
st   ──────┘
783  
784  lemma comap_domain_apply {α₁ α₂ γ : Type*} [has_zero γ]
id                                               └──────┘ 
src                                              └──────┘
typ                                              └──────┘ 
785    (f : α₁ → α₂) (l : α₂ →₀ γ) (hf : set.inj_on f (f ⁻¹' l.support.to_set)) (a : α₁) :
id          └┘   └┘       └┘ └┘         └────────┘    └─┘ └──────┘└─────┘        └┘
src                          └┘          └────────┘      └─┘  └──────┘└─────┘
typ         └┘   └┘       └┘ └┘         └────────┘    └─┘ └──────┘└─────┘        └┘
doc                          └┘          └────────┘      └─┘          └─────┘
786    comap_domain f l hf a = l (f a) :=
id     └──────────┘   └┘      
src    └──────────┘          
typ    └──────────┘   └┘      
787  begin
st   └─────
788    unfold_coes,
src    └─────────┘
typ    └─────────┘
doc    └─────────┘
txt    └─────────┘
par    └─────────┘
st   ────────────┘└─
789    unfold comap_domain,
src    └─────────────────┘
typ    └─────────────────┘
doc    └─────────────────┘
txt    └─────────────────┘
par    └─────────────────┘
pid          └───────────┘
st   ────────────────────┘└─
790    simp,
src    └──┘
typ    └──┘
doc    └──┘
txt    └──┘
par    └──┘
st   ─────┘└─
791    refl
src    └───┘
typ    └───┘
doc    └───┘
txt    └───┘
par    └───┘
pid        
st   ──────┘
792  end
st   └─┘
793  
794  lemma sum_comap_domain {α₁ α₂ β γ : Type*} [has_zero β] [add_comm_monoid γ]
id                                               └──────┘    └─────────────┘ 
src                                              └──────┘     └─────────────┘
typ                                              └──────┘    └─────────────┘ 
795    (f : α₁ → α₂) (l : α₂ →₀ β) (g : α₂ → β → γ) (hf : set.bij_on f (f ⁻¹' l.support.to_set) l.support.to_set):
id          └┘   └┘       └┘ └┘        └┘              └────────┘    └─┘ └──────┘└─────┘  └──────┘└─────┘
src                          └┘                           └────────┘      └─┘  └──────┘└─────┘   └──────┘└─────┘
typ         └┘   └┘       └┘ └┘        └┘              └────────┘    └─┘ └──────┘└─────┘  └──────┘└─────┘
doc                          └┘                           └────────┘      └─┘          └─────┘           └─────┘
796    (comap_domain f l (set.inj_on_of_bij_on hf)).sum (g ∘ f) = l.sum g :=
id      └──────────┘    └──────────────────┘ └┘  └─┘        └──┘ 
src     └──────────┘      └──────────────────┘     └─┘           └──┘
typ     └──────────┘    └──────────────────┘ └┘  └─┘        └──┘ 
doc                                                └─┘             └──┘
797  begin
st   └─────
798    unfold sum,
src    └────────┘
typ    └────────┘
doc    └────────┘
txt    └────────┘
par    └────────┘
pid          └──┘
st   ───────────┘└─
799    haveI := classical.dec_eq α₂,
id              └──────────────┘ └┘
src    └───────┘└──────────────┘
typ    └───────┘└──────────────┘└┘
doc    └───────┘                
txt    └───────┘                
par    └───────┘                
pid         └─┘                
st   ─────────────────────────────┘└─
800    simp only [comap_domain, comap_domain_apply, finset.sum_preimage f _ _ (λ (x : α₂), g x (l x))],
id                └──────────┘  └────────────────┘  └─────────────────┘              └┘       
src    └─────────┘└──────────┘└┘└────────────────┘└┘└─────────────────┘ └───┘  └────┘  └─┘     └─┘
typ    └─────────┘└──────────┘└┘└────────────────┘└┘└─────────────────┘└───┘  └────┘└┘└─┘   └─┘
doc    └─────────┘            └┘                  └┘                    └───┘  └────┘  └─┘     └─┘
txt    └─────────┘            └┘                  └┘                    └───┘  └────┘  └─┘     └─┘
par    └─────────┘            └┘                  └┘                    └───┘  └────┘  └─┘     └─┘
pid        └──┘└┘            └┘                  └┘                    └───┘  └────┘  └─┘     └─┘
st   ────────────────────────────────────────────────────────────────────────────────────────────────┘└─
801  end
st   ──┘
802  
803  lemma eq_zero_of_comap_domain_eq_zero {α₁ α₂ γ : Type*} [add_comm_monoid γ]
id                                                            └─────────────┘ 
src                                                           └─────────────┘
typ                                                           └─────────────┘ 
804    (f : α₁ → α₂) (l : α₂ →₀ γ) (hf : set.bij_on f (f ⁻¹' l.support.to_set) l.support.to_set) :
id          └┘   └┘       └┘ └┘         └────────┘    └─┘ └──────┘└─────┘  └──────┘└─────┘
src                          └┘          └────────┘      └─┘  └──────┘└─────┘   └──────┘└─────┘
typ         └┘   └┘       └┘ └┘         └────────┘    └─┘ └──────┘└─────┘  └──────┘└─────┘
doc                          └┘          └────────┘      └─┘          └─────┘           └─────┘
805     comap_domain f l (set.inj_on_of_bij_on hf) = 0 → l = 0 :=
id      └──────────┘    └──────────────────┘ └┘        
src     └──────────┘      └──────────────────┘            
typ     └──────────┘    └──────────────────┘ └┘        
806  begin
st   └─────
807    rw [← support_eq_empty, ← support_eq_empty, comap_domain],
id           └──────────────┘    └──────────────┘  └──────────┘
src    └────┘└──────────────┘└──┘└──────────────┘└┘└──────────┘
typ    └────┘└──────────────┘└──┘└──────────────┘└┘└──────────┘
doc    └────┘                └──┘                └┘            
txt    └────┘                └──┘                └┘            
par    └────┘                └──┘                └┘            
pid      └──┘                └──┘                └┘            
st   ───────────────────────┘└──────────────────┘└────────────┘└──
808    simp only [finset.ext, finset.not_mem_empty, iff_false, mem_preimage],
id                └────────┘  └──────────────────┘  └───────┘  └──────────┘
src    └─────────┘└────────┘└┘└──────────────────┘└┘└───────┘└┘└──────────┘
typ    └─────────┘└────────┘└┘└──────────────────┘└┘└───────┘└┘└──────────┘
doc    └─────────┘          └┘                    └┘         └┘            
txt    └─────────┘          └┘                    └┘         └┘            
par    └─────────┘          └┘                    └┘         └┘            
pid        └──┘└┘          └┘                    └┘         └┘            
st   ──────────────────────────────────────────────────────────────────────┘└─
809    assume h a ha,
src    └───────────┘
typ    └───────────┘
doc    └───────────┘
txt    └───────────┘
par    └───────────┘
pid    └───────────┘
st   ──────────────┘└─
810    cases hf.2.2 ha with b hb,
id           └┘     └┘
src    └────┘  └───┘  └────────┘
typ    └────┘└┘└───┘└┘└────────┘
doc    └────┘  └───┘  └────────┘
txt    └────┘  └───┘  └────────┘
par    └────┘  └───┘  └────────┘
pid           └───┘  └────────┘
st   ──────────────────────────┘└─
811    exact h b (hb.2.symm ▸ ha)
id              └┘         └┘
src    └────┘     └──────┘  └┘
typ    └────┘ └┘└──────┘└┘└┘
doc    └────┘     └──────┘   └┘
txt    └────┘     └──────┘   └┘
par    └────┘     └──────┘   └┘
pid              └──────┘   
st   ────────────────────────────┘
812  end
st   └─┘
813  
814  lemma map_domain_comap_domain {α₁ α₂ γ : Type*} [add_comm_monoid γ]
id                                                    └─────────────┘ 
src                                                   └─────────────┘
typ                                                   └─────────────┘ 
815    (f : α₁ → α₂) (l : α₂ →₀ γ)
id          └┘   └┘       └┘ └┘ 
src                          └┘
typ         └┘   └┘       └┘ └┘ 
doc                          └┘
816    (hf : function.injective f) (hl : ↑l.support ⊆ set.range f):
id           └────────────────┘         └──────┘  └───────┘ 
src          └────────────────┘           └──────┘  └───────┘
typ          └────────────────┘         └──────┘  └───────┘ 
doc                                                   └───────┘
817    map_domain f (comap_domain f l (set.inj_on_of_injective _ hf)) = l :=
id     └────────┘   └──────────┘    └─────────────────────┘   └┘    
src    └────────┘    └──────────┘      └─────────────────────┘        
typ    └────────┘   └──────────┘    └─────────────────────┘   └┘    
doc    └────────┘
818  begin
st   └─────
819    ext a,
src    └───┘
typ    └───┘
doc    └───┘
txt    └───┘
par    └───┘
pid       └┘
st   ──────┘└─
820    haveI := classical.dec (a ∈ set.range f),
id              └───────────┘    └───────┘ 
src    └───────┘└───────────┘  └───────┘ 
typ    └───────┘└───────────┘ └───────┘
doc    └───────┘                └───────┘ 
txt    └───────┘                          
par    └───────┘                          
pid         └─┘                          
st   ─────────────────────────────────────────┘└─
821    by_cases h_cases: a ∈ set.range f,
id                          └───────┘ 
src    └───────┘       └┘  └───────┘
typ    └───────┘       └┘ └───────┘
doc    └───────┘       └┘  └───────┘
txt    └───────┘       └┘           
par    └───────┘       └┘           
pid                   └┘           
st   ──────────────────────────────────┘└─
822    { rcases set.mem_range.1 h_cases with ⟨b, hb⟩,
id              └───────────┘   └─────┘
src      └─────┘└───────────┘└─┘       └───────────┘
typ      └─────┘└───────────┘└─┘└─────┘└───────────┘
doc      └─────┘             └─┘       └───────────┘
txt      └─────┘             └─┘       └───────────┘
par      └─────┘             └─┘       └───────────┘
pid                         └─┘       └───────────┘
st   ───┘└─────────────────────────────────────────┘└─
823      rw [hb.symm, map_domain_apply hf, comap_domain_apply] },
id                    └──────────────┘ └┘  └────────────────┘
src      └──┘       └┘└──────────────┘  └┘└────────────────┘└┘
typ      └──┘└─────┘└┘└──────────────┘└┘└┘└────────────────┘└┘
doc      └──┘       └┘                  └┘                  └┘
txt      └──┘       └┘                  └┘                  └┘
par      └──┘       └┘                  └┘                  └┘
pid        └┘       └┘                  └┘                  
st   ──────────────┘└───────────────────┘└──────────────────┘└┘
824    { rw map_domain_notin_range _ _ h_cases,
id          └────────────────────┘     └─────┘
src      └─┘└────────────────────┘└───┘
typ      └─┘└────────────────────┘└───┘└─────┘
doc      └─┘                      └───┘
txt      └─┘                      └───┘
par      └─┘                      └───┘
pid                              └───┘
st   ────────────────────────────────────────┘└─
825      by_contra h_contr,
src      └───────────────┘
typ      └───────────────┘
doc      └───────────────┘
txt      └───────────────┘
par      └───────────────┘
pid               └──────┘
st   ────────────────────┘└─
826      apply h_cases (hl (finset.mem_coe.2 (mem_support_iff.2 (λ h, h_contr h.symm)))) }
id             └─────┘  └┘  └────────────┘    └─────────────┘         └─────┘  └───┘
src      └────┘           └────────────┘└─┘ └─────────────┘└─┘  └──┘        └───┘└───┘
typ      └────┘└─────┘ └┘ └────────────┘└─┘ └─────────────┘└─┘  └──┘└─────┘ └───┘└───┘
doc      └────┘                         └─┘                └─┘  └──┘             └───┘
txt      └────┘                         └─┘                └─┘  └──┘             └───┘
par      └────┘                         └─┘                └─┘  └──┘             └───┘
pid                                    └─┘                └─┘  └──┘             └──┘
st   ───────────────────────────────────────────────────────────────────────────────────┘└─
827  end
st   ──┘
828  
829  end comap_domain
830  
831  /-- The product of `f g : α →₀ β` is the finitely supported function
832    whose value at `a` is the sum of `f x * g y` over all pairs `x, y`
833    such that `x + y = a`. (Think of the product of multivariate
834    polynomials where `α` is the monoid of monomial exponents.) -/
835  instance [has_add α] [semiring β] : has_mul (α →₀ β) :=
id             └─────┘    └──────┘     └─────┘   └┘ 
src            └─────┘     └──────┘      └─────┘    └┘
typ            └─────┘    └──────┘     └─────┘   └┘ 
doc                                                 └┘
836  ⟨λf g, f.sum $ λa₁ b₁, g.sum $ λa₂ b₂, single (a₁ + a₂) (b₁ * b₂)⟩
id        └──┘    └┘ └┘  └──┘    └┘ └┘  └────┘  └┘  └┘   └┘  └┘
src          └──┘            └──┘           └────┘              
typ       └──┘    └┘ └┘  └──┘    └┘ └┘  └────┘  └┘  └┘   └┘  └┘
doc          └──┘            └──┘           └────┘
837  
838  lemma mul_def [has_add α] [semiring β] {f g : α →₀ β} :
id                  └─────┘    └──────┘           └┘ 
src                 └─────┘     └──────┘             └┘
typ                 └─────┘    └──────┘           └┘ 
doc                                                  └┘
839    f * g = (f.sum $ λa₁ b₁, g.sum $ λa₂ b₂, single (a₁ + a₂) (b₁ * b₂)) := rfl
id          └──┘    └┘ └┘  └──┘    └┘ └┘  └────┘  └┘  └┘   └┘  └┘      └─┘
src            └──┘            └──┘           └────┘                       └─┘
typ         └──┘    └┘ └┘  └──┘    └┘ └┘  └────┘  └┘  └┘   └┘  └┘      └─┘
doc              └──┘            └──┘           └────┘
840  
841  lemma support_mul [has_add α] [semiring β] (a b : α →₀ β) :
id                      └─────┘    └──────┘           └┘ 
src                     └─────┘     └──────┘             └┘
typ                     └─────┘    └──────┘           └┘ 
doc                                                      └┘
842    (a * b).support ⊆ a.support.bind (λa₁, b.support.bind $ λa₂, {a₁ + a₂}) :=
id         └─────┘   └──────┘└───┘   └┘  └──────┘└───┘    └┘  └┘  └┘
src          └─────┘    └──────┘└───┘        └──────┘└───┘           
typ        └─────┘   └──────┘└───┘   └┘  └──────┘└───┘    └┘  └┘  └┘
doc                               └───┘                └───┘
843  subset.trans support_sum $ bind_mono $ assume a₁ _,
id   └──────────┘ └─────────┘   └───────┘          └┘ 
src  └──────────┘ └─────────┘   └───────┘
typ  └──────────┘ └─────────┘   └───────┘          └┘ 
844    subset.trans support_sum $ bind_mono $ assume a₂ _, support_single_subset
id     └──────────┘ └─────────┘   └───────┘          └┘   └───────────────────┘
src    └──────────┘ └─────────┘   └───────┘                └───────────────────┘
typ    └──────────┘ └─────────┘   └───────┘          └┘   └───────────────────┘
845  
846  /-- The unit of the multiplication is `single 0 1`, i.e. the function
847    that is 1 at 0 and zero elsewhere. -/
848  instance [has_zero α] [has_zero β] [has_one β] : has_one (α →₀ β) :=
id             └──────┘    └──────┘    └─────┘     └─────┘   └┘ 
src            └──────┘     └──────┘     └─────┘      └─────┘    └┘
typ            └──────┘    └──────┘    └─────┘     └─────┘   └┘ 
doc                                                              └┘
849  ⟨single 0 1⟩
id    └────┘
src   └────┘
typ   └────┘
doc   └────┘
850  
851  lemma one_def [has_zero α] [has_zero β] [has_one β] : 1 = (single 0 1 : α →₀ β) := rfl
id                  └──────┘    └──────┘    └─────┘         └────┘        └┘      └─┘
src                 └──────┘     └──────┘     └─────┘          └────┘         └┘       └─┘
typ                 └──────┘    └──────┘    └─────┘         └────┘        └┘      └─┘
doc                                                             └────┘         └┘
852  
853  section filter
854  section has_zero
855  variables [has_zero β] (p : α → Prop) (f : α →₀ β)
id              └──────┘                          └┘
src             └──────┘                          └┘
typ             └──────┘                          └┘
doc                                               └┘
856  
857  /-- `filter p f` is the function which is `f a` if `p a` is true and 0 otherwise. -/
858  def filter (p : α → Prop) (f : α →₀ β) : α →₀ β :=
id                                  └┘      └┘ 
src                                   └┘        └┘
typ                                 └┘      └┘ 
doc                                   └┘        └┘
859  on_finset f.support (λa, if p a then f a else 0) $ λ a H,
id   └───────┘ └──────┘                              
src  └───────┘  └──────┘
typ  └───────┘ └──────┘                              
doc  └───────┘
860  mem_support_iff.2 $ λ h, by rw [h, if_t_t] at H; exact H rfl
id   └─────────────┘                 └────┘               └─┘
src  └─────────────┘            └──┘ └┘└────┘└────┘  └────┘ └─┘
typ  └─────────────┘           └──┘└┘└────┘└────┘  └────┘└─┘
doc                              └──┘ └┘      └────┘  └────┘    
txt                              └──┘ └┘      └────┘  └────┘    
par                              └──┘ └┘      └────┘  └────┘    
pid                                └┘ └┘      └───┘           
st                              └────┘└──────┘└──────────────────
861  
src  
typ  
doc  
txt  
par  
pid  
st   
862  @[simp] lemma filter_apply_pos {a : α} (h : p a) : f.filter p a = f a :=
id                                                   └─────┘     
src                                                      └─────┘     
typ                                                  └─────┘     
doc    └──┘                                              └─────┘
863  if_pos h
id   └────┘ 
src  └────┘
typ  └────┘ 
864  
865  @[simp] lemma filter_apply_neg {a : α} (h : ¬ p a) : f.filter p a = 0 :=
id                                                    └─────┘   
src                                                       └─────┘     
typ                                                   └─────┘   
doc    └──┘                                                └─────┘
866  if_neg h
id   └────┘ 
src  └────┘
typ  └────┘ 
867  
868  @[simp] lemma support_filter : (f.filter p).support = f.support.filter p :=
id                                   └─────┘  └─────┘   └──────┘└─────┘ 
src                                   └─────┘   └─────┘    └──────┘└─────┘
typ                                  └─────┘  └─────┘   └──────┘└─────┘ 
doc    └──┘                           └─────┘                       └─────┘
869  finset.ext.mpr $ assume a, if H : p a
id   └────────┘└──┘            └┘      
src  └────────┘└──┘             └┘
typ  └────────┘└──┘            └┘      
870  then by simp only [mem_support_iff, filter_apply_pos _ _ H, mem_filter, H, and_true]
id                      └─────────────┘  └──────────────┘       └────────┘    └──────┘
src          └─────────┘└─────────────┘└┘└──────────────┘└───┘ └┘└────────┘└┘ └┘└──────┘└┘
typ          └─────────┘└─────────────┘└┘└──────────────┘└───┘└┘└────────┘└┘└┘└──────┘└┘
doc          └─────────┘               └┘                └───┘ └┘          └┘ └┘        └┘
txt          └─────────┘               └┘                └───┘ └┘          └┘ └┘        └┘
par          └─────────┘               └┘                └───┘ └┘          └┘ └┘        └┘
pid              └──┘└┘               └┘                └───┘ └┘          └┘ └┘        
st          └────────────────────────────────────────────────────────────────────────────┘
871  else by simp only [mem_support_iff, filter_apply_neg _ _ H, mem_filter, H, and_false, ne.def, ne_self_iff_false]
id                      └─────────────┘  └──────────────┘       └────────┘    └───────┘  └────┘  └───────────────┘
src          └─────────┘└─────────────┘└┘└──────────────┘└───┘ └┘└────────┘└┘ └┘└───────┘└┘└────┘└┘└───────────────┘└─
typ          └─────────┘└─────────────┘└┘└──────────────┘└───┘└┘└────────┘└┘└┘└───────┘└┘└────┘└┘└───────────────┘└─
doc          └─────────┘               └┘                └───┘ └┘          └┘ └┘         └┘      └┘                 └─
txt          └─────────┘               └┘                └───┘ └┘          └┘ └┘         └┘      └┘                 └─
par          └─────────┘               └┘                └───┘ └┘          └┘ └┘         └┘      └┘                 └─
pid              └──┘└┘               └┘                └───┘ └┘          └┘ └┘         └┘      └┘                 
st          └─────────────────────────────────────────────────────────────────────────────────────────────────────────
872  
src  
typ  
doc  
txt  
par  
pid  
st   
873  lemma filter_zero : (0 : α →₀ β).filter p = 0 :=
id                             └┘  └────┘   
src                             └┘   └────┘    
typ                            └┘  └────┘   
doc                             └┘   └────┘
874  by rw [← support_eq_empty, support_filter, support_zero, finset.filter_empty]
id            └──────────────┘  └────────────┘  └──────────┘  └─────────────────┘
src     └────┘└──────────────┘└┘└────────────┘└┘└──────────┘└┘└─────────────────┘└─
typ     └────┘└──────────────┘└┘└────────────┘└┘└──────────┘└┘└─────────────────┘└─
doc     └────┘                └┘              └┘            └┘                   └─
txt     └────┘                └┘              └┘            └┘                   └─
par     └────┘                └┘              └┘            └┘                   └─
pid       └──┘                └┘              └┘            └┘                   
st     └─────────────────────┘└──────────────┘└────────────┘└───────────────────┘
875  
src  
typ  
doc  
txt  
par  
pid  
st   
876  @[simp] lemma filter_single_of_pos
doc    └──┘
877    {a : α} {b : β} (h : p a) : (single a b).filter p = single a b :=
id                              └────┘   └────┘    └────┘  
src                                 └────┘     └────┘     └────┘
typ                             └────┘   └────┘    └────┘  
doc                                 └────┘     └────┘      └────┘
878  finsupp.ext $ λ x, begin
id   └─────────┘     
src  └─────────┘
typ  └─────────┘     
st                      └─────
879    by_cases h' : p x; simp [h'],
id                            └┘
src    └───────┘  └─┘    └────┘  
typ    └───────┘  └─┘  └────┘└┘
doc    └───────┘  └─┘    └────┘  
txt    └───────┘  └─┘    └────┘  
par    └───────┘  └─┘    └────┘  
pid              └─┘          
st   ─────────────────────────────┘└─
880    rw single_eq_of_ne, rintro rfl, exact h' h
id        └─────────────┘                    └┘ 
src    └─┘└─────────────┘  └────────┘  └────┘   
typ    └─┘└─────────────┘  └────────┘  └────┘└┘
doc    └─┘                 └────────┘  └────┘   
txt    └─┘                 └────────┘  └────┘   
par    └─┘                 └────────┘  └────┘   
pid                             └──┘          
st   ───────────────────┘└──────────┘└───────────┘
881  end
st   └─┘
882  
883  @[simp] lemma filter_single_of_neg
doc    └──┘
884    {a : α} {b : β} (h : ¬ p a) : (single a b).filter p = 0 :=
id                               └────┘   └────┘   
src                                  └────┘     └────┘    
typ                              └────┘   └────┘   
doc                                   └────┘     └────┘
885  finsupp.ext $ λ x, begin
id   └─────────┘     
src  └─────────┘
typ  └─────────┘     
st                      └─────
886    by_cases h' : p x; simp [h'],
id                            └┘
src    └───────┘  └─┘    └────┘  
typ    └───────┘  └─┘  └────┘└┘
doc    └───────┘  └─┘    └────┘  
txt    └───────┘  └─┘    └────┘  
par    └───────┘  └─┘    └────┘  
pid              └─┘          
st   ─────────────────────────────┘└─
887    rw single_eq_of_ne, rintro rfl, exact h h'
id        └─────────────┘                     └┘
src    └─┘└─────────────┘  └────────┘  └────┘   
typ    └─┘└─────────────┘  └────────┘  └────┘└┘
doc    └─┘                 └────────┘  └────┘   
txt    └─┘                 └────────┘  └────┘   
par    └─┘                 └────────┘  └────┘   
pid                             └──┘          
st   ───────────────────┘└──────────┘└───────────┘
888  end
st   └─┘
889  
890  end has_zero
891  
892  lemma filter_pos_add_filter_neg [add_monoid β] (f : α →₀ β) (p : α → Prop) :
id                                    └────────┘         └┘        
src                                   └────────┘           └┘
typ                                   └────────┘         └┘        
doc                                                        └┘
893    f.filter p + f.filter (λa, ¬ p a) = f :=
id     └─────┘   └─────┘          
src     └─────┘     └─────┘            
typ    └─────┘   └─────┘          
doc     └─────┘      └─────┘
894  finsupp.ext $ assume a, if H : p a
id   └─────────┘            └┘      
src  └─────────┘             └┘
typ  └─────────┘            └┘      
895  then by simp only [add_apply, filter_apply_pos, filter_apply_neg, H, not_not, add_zero]
id                      └───────┘  └──────────────┘  └──────────────┘    └─────┘  └──────┘
src          └─────────┘└───────┘└┘└──────────────┘└┘└──────────────┘└┘ └┘└─────┘└┘└──────┘└┘
typ          └─────────┘└───────┘└┘└──────────────┘└┘└──────────────┘└┘└┘└─────┘└┘└──────┘└┘
doc          └─────────┘         └┘                └┘                └┘ └┘       └┘        └┘
txt          └─────────┘         └┘                └┘                └┘ └┘       └┘        └┘
par          └─────────┘         └┘                └┘                └┘ └┘       └┘        └┘
pid              └──┘└┘         └┘                └┘                └┘ └┘       └┘        
st          └───────────────────────────────────────────────────────────────────────────────┘
896  else by simp only [add_apply, filter_apply_pos, filter_apply_neg, H, not_false_iff, zero_add]
id                      └───────┘  └──────────────┘  └──────────────┘    └───────────┘  └──────┘
src          └─────────┘└───────┘└┘└──────────────┘└┘└──────────────┘└┘ └┘└───────────┘└┘└──────┘└─
typ          └─────────┘└───────┘└┘└──────────────┘└┘└──────────────┘└┘└┘└───────────┘└┘└──────┘└─
doc          └─────────┘         └┘                └┘                └┘ └┘             └┘        └─
txt          └─────────┘         └┘                └┘                └┘ └┘             └┘        └─
par          └─────────┘         └┘                └┘                └┘ └┘             └┘        └─
pid              └──┘└┘         └┘                └┘                └┘ └┘             └┘        
st          └──────────────────────────────────────────────────────────────────────────────────────
897  
src  
typ  
doc  
txt  
par  
pid  
st   
898  end filter
899  
900  section frange
901  variables [has_zero β]
id              └──────┘
src             └──────┘
typ             └──────┘
902  
903  def frange (f : α →₀ β) : finset β :=
id                    └┘     └────┘ 
src                    └┘      └────┘
typ                   └┘     └────┘ 
doc                    └┘      └────┘
904  finset.image f f.support
id   └──────────┘  └──────┘
src  └──────────┘    └──────┘
typ  └──────────┘  └──────┘
doc  └──────────┘
905  
906  theorem mem_frange {f : α →₀ β} {y : β} :
id                            └┘        
src                            └┘
typ                           └┘        
doc                            └┘
907    y ∈ f.frange ↔ y ≠ 0 ∧ ∃ x, f x = y :=
id       └─────┘            
src        └─────┘               
typ      └─────┘            
908  finset.mem_image.trans
id   └──────────────┘└────┘
src  └──────────────┘└────┘
typ  └──────────────┘└────┘
909  ⟨λ ⟨x, hx1, hx2⟩, ⟨hx2 ▸ mem_support_iff.1 hx1, x, hx2⟩,
id        └─┘  └─┘         └─────────────┘
src                          └─────────────┘
typ       └─┘  └─┘         └─────────────┘
910  λ ⟨hy, x, hx⟩, ⟨x, mem_support_iff.2 (hx.symm ▸ hy), hx⟩⟩
id     └┘    └┘       └─────────────┘     └───┘ 
src                     └─────────────┘     └───┘ 
typ    └┘    └┘       └─────────────┘     └───┘ 
911  
912  theorem zero_not_mem_frange {f : α →₀ β} : (0:β) ∉ f.frange :=
id                                     └┘           └─────┘
src                                     └┘              └─────┘
typ                                    └┘           └─────┘
doc                                     └┘
913  λ H, (mem_frange.1 H).1 rfl
id        └────────┘     └─┘
src        └────────┘      └─┘
typ       └────────┘     └─┘
914  
915  theorem frange_single {x : α} {y : β} : frange (single x y) ⊆ {y} :=
id                                         └────┘  └────┘     
src                                          └────┘  └────┘       
typ                                        └────┘  └────┘     
doc                                                  └────┘
916  λ r hr, let ⟨t, ht1, ht2⟩ := mem_frange.1 hr in ht2 ▸
id      └┘  └─┘          └─┘     └────────┘  └┘        
src                               └────────┘            
typ     └┘  └─┘          └─┘     └────────┘  └┘        
917  (by rw single_apply at ht2 ⊢; split_ifs at ht2 ⊢; [exact finset.mem_singleton_self _, cc])
id          └──────────┘                                     └───────────────────────┘
src      └─┘└──────────┘└───────┘  └────────────────┘  └────┘└───────────────────────┘└┘  └┘
typ      └─┘└──────────┘└───────┘  └────────────────┘  └────┘└───────────────────────┘└┘  └┘
doc      └─┘            └───────┘  └────────────────┘   └────┘                         └┘  └┘
txt      └─┘            └───────┘  └────────────────┘   └────┘                         └┘  └┘
par      └─┘            └───────┘  └────────────────┘   └────┘                         └┘  └┘
pid                    └───────┘           └───────┘                                 └┘
st      └────────────────────────────────────────────────────────────────────────────────────┘
918  
919  end frange
920  
921  section subtype_domain
922  
923  variables {α' : Type*} [has_zero δ] {p : α → Prop}
id                           └──────┘
src                          └──────┘
typ                          └──────┘
924  
925  section zero
926  variables [has_zero β] {v v' : α' →₀ β}
id              └──────┘               └┘
src             └──────┘               └┘
typ             └──────┘               └┘
doc                                    └┘
927  
928  /-- `subtype_domain p f` is the restriction of the finitely supported function
929    `f` to the subtype `p`. -/
930  def subtype_domain (p : α → Prop) (f : α →₀ β) : (subtype p →₀ β) :=
id                                          └┘      └─────┘  └┘ 
src                                           └┘       └─────┘   └┘
typ                                         └┘      └─────┘  └┘ 
doc                                           └┘                 └┘
931  ⟨f.support.subtype p, f ∘ subtype.val, λ a, by simp only [mem_subtype, mem_support_iff]⟩
id    └──────┘└──────┘     └─────────┘                    └─────────┘  └─────────────┘
src    └──────┘└──────┘       └─────────┘          └─────────┘└─────────┘└┘└─────────────┘
typ   └──────┘└──────┘     └─────────┘         └─────────┘└─────────┘└┘└─────────────┘
doc                                                 └─────────┘           └┘               
txt                                                 └─────────┘           └┘               
par                                                 └─────────┘           └┘               
pid                                                     └──┘└┘           └┘               
st                                                 └───────────────────────────────────────┘
932  
933  @[simp] lemma support_subtype_domain {f : α →₀ β} :
id                                              └┘ 
src                                              └┘
typ                                             └┘ 
doc    └──┘                                      └┘
934    (subtype_domain p f).support = f.support.subtype p :=
id      └────────────┘   └─────┘   └──────┘└──────┘ 
src     └────────────┘     └─────┘    └──────┘└──────┘
typ     └────────────┘   └─────┘   └──────┘└──────┘ 
doc     └────────────┘
935  rfl
id   └─┘
src  └─┘
typ  └─┘
936  
937  @[simp] lemma subtype_domain_apply {a : subtype p} {v : α →₀ β} :
id                                           └─────┘         └┘ 
src                                          └─────┘           └┘
typ                                          └─────┘         └┘ 
doc    └──┘                                                    └┘
938    (subtype_domain p v) a = v (a.val) :=
id      └────────────┘        └──┘
src     └────────────┘             └──┘
typ     └────────────┘        └──┘
doc     └────────────┘
939  rfl
id   └─┘
src  └─┘
typ  └─┘
940  
941  @[simp] lemma subtype_domain_zero : subtype_domain p (0 : α →₀ β) = 0 :=
id                                       └────────────┘        └┘   
src                                      └────────────┘          └┘    
typ                                      └────────────┘        └┘   
doc    └──┘                              └────────────┘          └┘
942  rfl
id   └─┘
src  └─┘
typ  └─┘
943  
944  @[to_additive]
doc    └─────────┘
945  lemma prod_subtype_domain_index [comm_monoid γ] {v : α →₀ β}
id                                    └─────────┘         └┘ 
src                                   └─────────┘           └┘
typ                                   └─────────┘         └┘ 
doc                                                         └┘
946    {h : α → β → γ} (hp : ∀x∈v.support, p x) :
id                          └──────┘   
src                              └──────┘
typ                         └──────┘   
947    (v.subtype_domain p).prod (λa b, h a.1 b) = v.prod h :=
id      └─────────────┘  └──┘             └───┘ 
src      └─────────────┘   └──┘                   └───┘
typ     └─────────────┘  └──┘             └───┘ 
doc      └─────────────┘   └──┘                     └───┘
948  prod_bij (λp _, p.val)
id   └──────┘      └──┘
src  └──────┘         └──┘
typ  └──────┘      └──┘
949    (λ _, mem_subtype.1)
id          └─────────┘
src          └─────────┘
typ         └─────────┘
950    (λ _ _, rfl)
id           └─┘
src            └─┘
typ          └─┘
951    (λ _ _ _ _, subtype.eq)
id             └────────┘
src                └────────┘
typ            └────────┘
952    (λ b hb, ⟨⟨b, hp b hb⟩, mem_subtype.2 hb, rfl⟩)
id         └┘      └┘  └┘   └─────────┘  └┘  └─┘
src                            └─────────┘      └─┘
typ        └┘      └┘  └┘   └─────────┘  └┘  └─┘
953  
954  end zero
955  
956  section monoid
957  variables [add_monoid β] {v v' : α' →₀ β}
id              └────────┘               └┘
src             └────────┘               └┘
typ             └────────┘               └┘
doc                                      └┘
958  
959  @[simp] lemma subtype_domain_add {v v' : α →₀ β} :
id                                             └┘ 
src                                             └┘
typ                                            └┘ 
doc    └──┘                                     └┘
960    (v + v').subtype_domain p = v.subtype_domain p + v'.subtype_domain p :=
id        └┘ └────────────┘    └─────────────┘   └┘└─────────────┘ 
src           └────────────┘      └─────────────┘      └─────────────┘
typ       └┘ └────────────┘    └─────────────┘   └┘└─────────────┘ 
doc            └────────────┘       └─────────────┘       └─────────────┘
961  ext $ λ _, rfl
id   └─┘       └─┘
src  └─┘        └─┘
typ  └─┘       └─┘
962  
963  instance subtype_domain.is_add_monoid_hom :
964    is_add_monoid_hom (subtype_domain p : (α →₀ β) → subtype p →₀ β) :=
id     └───────────────┘  └────────────┘      └┘     └─────┘  └┘ 
src    └───────────────┘  └────────────┘        └┘      └─────┘   └┘
typ    └───────────────┘  └────────────┘      └┘     └─────┘  └┘ 
doc    └───────────────┘  └────────────┘        └┘                └┘
965  { map_add := λ _ _, subtype_domain_add, map_zero := subtype_domain_zero }
id                     └────────────────┘              └─────────────────┘
src                      └────────────────┘              └─────────────────┘
typ                    └────────────────┘              └─────────────────┘
966  
967  @[simp] lemma filter_add {v v' : α →₀ β} :
id                                     └┘ 
src                                     └┘
typ                                    └┘ 
doc    └──┘                             └┘
968    (v + v').filter p = v.filter p + v'.filter p :=
id        └┘ └────┘    └─────┘   └┘└─────┘ 
src           └────┘      └─────┘      └─────┘
typ       └┘ └────┘    └─────┘   └┘└─────┘ 
doc            └────┘       └─────┘       └─────┘
969  ext $ λ a, by by_cases p a; simp [h]
id   └─┘                            
src  └─┘           └───────┘    └────┘ └─
typ  └─┘          └───────┘  └────┘└─
doc                └───────┘    └────┘ └─
txt                └───────┘    └────┘ └─
par                └───────┘    └────┘ └─
pid                                 
st                └───────────────────────
970  
src  
typ  
doc  
txt  
par  
pid  
st   
971  instance filter.is_add_monoid_hom (p : α → Prop) :
id                                          
typ                                         
972    is_add_monoid_hom (filter p : (α →₀ β) → (α →₀ β)) :=
id     └───────────────┘  └────┘      └┘       └┘ 
src    └───────────────┘  └────┘        └┘         └┘
typ    └───────────────┘  └────┘      └┘       └┘ 
doc    └───────────────┘  └────┘        └┘         └┘
973  { map_zero := filter_zero p, map_add := λ x y, filter_add }
id                 └─────────┘                   └────────┘
src                └─────────┘                      └────────┘
typ                └─────────┘                   └────────┘
974  
975  end monoid
976  
977  section comm_monoid
978  variables [add_comm_monoid β]
id              └─────────────┘
src             └─────────────┘
typ             └─────────────┘
979  
980  lemma subtype_domain_sum {s : finset γ} {h : γ → α →₀ β} :
id                                 └────┘            └┘ 
src                                └────┘               └┘
typ                                └────┘            └┘ 
doc                                └────┘               └┘
981    (s.sum h).subtype_domain p = s.sum (λc, (h c).subtype_domain p) :=
id      └──┘  └────────────┘    └──┘        └────────────┘  
src      └──┘   └────────────┘      └──┘           └────────────┘
typ     └──┘  └────────────┘    └──┘        └────────────┘  
doc             └────────────┘                      └────────────┘
982  eq.symm (s.sum_hom _)
id   └─────┘  └──────┘
src  └─────┘   └──────┘
typ  └─────┘  └──────┘
983  
984  lemma subtype_domain_finsupp_sum {s : γ →₀ δ} {h : γ → δ → α →₀ β} :
id                                          └┘               └┘ 
src                                          └┘                   └┘
typ                                         └┘               └┘ 
doc                                          └┘                   └┘
985    (s.sum h).subtype_domain p = s.sum (λc d, (h c d).subtype_domain p) :=
id      └──┘  └────────────┘    └──┘          └────────────┘  
src      └──┘   └────────────┘      └──┘               └────────────┘
typ     └──┘  └────────────┘    └──┘          └────────────┘  
doc      └──┘   └────────────┘       └──┘               └────────────┘
986  subtype_domain_sum
id   └────────────────┘
src  └────────────────┘
typ  └────────────────┘
987  
988  lemma filter_sum (s : finset γ) (f : γ → α →₀ β) :
id                         └────┘            └┘ 
src                        └────┘               └┘
typ                        └────┘            └┘ 
doc                        └────┘               └┘
989    (s.sum f).filter p = s.sum (λa, filter p (f a)) :=
id      └──┘  └────┘    └──┘     └────┘    
src      └──┘   └────┘      └──┘      └────┘
typ     └──┘  └────┘    └──┘     └────┘    
doc             └────┘                 └────┘
990  (s.sum_hom (filter p)).symm
id    └──────┘  └────┘   └──┘
src    └──────┘  └────┘    └──┘
typ   └──────┘  └────┘   └──┘
doc              └────┘
991  
992  end comm_monoid
993  
994  section group
995  variables [add_group β] {v v' : α' →₀ β}
id              └───────┘               └┘
src             └───────┘               └┘
typ             └───────┘               └┘
doc                                     └┘
996  
997  @[simp] lemma subtype_domain_neg {v : α →₀ β} :
id                                          └┘ 
src                                          └┘
typ                                         └┘ 
doc    └──┘                                  └┘
998    (- v).subtype_domain p = - v.subtype_domain p :=
id        └────────────┘     └─────────────┘ 
src        └────────────┘       └─────────────┘
typ       └────────────┘     └─────────────┘ 
doc         └────────────┘         └─────────────┘
999  ext $ λ _, rfl
id   └─┘       └─┘
src  └─┘        └─┘
typ  └─┘       └─┘
1000  
1001  @[simp] lemma subtype_domain_sub {v v' : α →₀ β} :
id                                             └┘ 
src                                             └┘
typ                                            └┘ 
doc    └──┘                                     └┘
1002    (v - v').subtype_domain p = v.subtype_domain p - v'.subtype_domain p :=
id        └┘ └────────────┘    └─────────────┘   └┘└─────────────┘ 
src           └────────────┘      └─────────────┘      └─────────────┘
typ       └┘ └────────────┘    └─────────────┘   └┘└─────────────┘ 
doc            └────────────┘       └─────────────┘       └─────────────┘
1003  ext $ λ _, rfl
id   └─┘       └─┘
src  └─┘        └─┘
typ  └─┘       └─┘
1004  
1005  end group
1006  
1007  end subtype_domain
1008  
1009  section multiset
1010  
1011  def to_multiset (f : α →₀ ℕ) : multiset α :=
id                         └┘     └──────┘ 
src                         └┘     └──────┘
typ                        └┘     └──────┘ 
doc                         └┘      └──────┘
1012  f.sum (λa n, add_monoid.smul n {a})
id   └──┘      └─────────────┘  
src   └──┘        └─────────────┘   
typ  └──┘      └─────────────┘  
doc   └──┘
1013  
1014  lemma to_multiset_zero : (0 : α →₀ ℕ).to_multiset = 0 :=
id                                  └┘  └─────────┘  
src                                  └┘  └─────────┘  
typ                                 └┘  └─────────┘  
doc                                  └┘
1015  rfl
id   └─┘
src  └─┘
typ  └─┘
1016  
1017  lemma to_multiset_add (m n : α →₀ ℕ) :
id                                 └┘ 
src                                 └┘ 
typ                                └┘ 
doc                                 └┘
1018    (m + n).to_multiset = m.to_multiset + n.to_multiset :=
id         └─────────┘   └──────────┘  └──────────┘
src          └─────────┘    └──────────┘   └──────────┘
typ        └─────────┘   └──────────┘  └──────────┘
1019  sum_add_index (assume a, add_monoid.zero_smul _) (assume a b₁ b₂, add_monoid.add_smul _ _ _)
id   └───────────┘           └──────────────────┘             └┘ └┘  └─────────────────┘
src  └───────────┘            └──────────────────┘                     └─────────────────┘
typ  └───────────┘           └──────────────────┘             └┘ └┘  └─────────────────┘
1020  
1021  lemma to_multiset_single (a : α) (n : ℕ) : to_multiset (single a n) = add_monoid.smul n {a} :=
id                                            └─────────┘  └────┘     └─────────────┘  
src                                            └─────────┘  └────┘       └─────────────┘   
typ                                           └─────────┘  └────┘     └─────────────┘  
doc                                                          └────┘
1022  by rw [to_multiset, sum_single_index]; apply add_monoid.zero_smul
id          └─────────┘  └──────────────┘         └──────────────────┘
src     └──┘└─────────┘└┘└──────────────┘  └────┘└──────────────────┘
typ     └──┘└─────────┘└┘└──────────────┘  └────┘└──────────────────┘
doc     └──┘           └┘                  └────┘                    
txt     └──┘           └┘                  └────┘                    
par     └──┘           └┘                  └────┘                    
pid       └┘           └┘                                           
st     └──────────────┘└────────────────┘└────────────────────────────
1023  
src  
typ  
doc  
txt  
par  
pid  
st   
1024  instance is_add_monoid_hom.to_multiset : is_add_monoid_hom (to_multiset : _ → multiset α) :=
id                                            └───────────────┘  └─────────┘      └──────┘ 
src                                           └───────────────┘  └─────────┘       └──────┘
typ                                           └───────────────┘  └─────────┘      └──────┘ 
doc                                           └───────────────┘                    └──────┘
1025  { map_zero := to_multiset_zero, map_add := to_multiset_add }
id                 └──────────────┘             └─────────────┘
src                └──────────────┘             └─────────────┘
typ                └──────────────┘             └─────────────┘
1026  
1027  lemma card_to_multiset (f : α →₀ ℕ) : f.to_multiset.card = f.sum (λa, id) :=
id                                └┘     └──────────┘└───┘  └──┘     └┘
src                                └┘      └──────────┘└───┘   └──┘      └┘
typ                               └┘     └──────────┘└───┘  └──┘     └┘
doc                                └┘                   └───┘    └──┘
1028  begin
st   └─────
1029    refine f.induction _ _,
id            └─────────┘
src    └─────┘└─────────┘└──┘
typ    └─────┘└─────────┘└──┘
doc    └─────┘           └──┘
txt    └─────┘           └──┘
par    └─────┘           └──┘
pid                     └──┘
st   ───────────────────────┘└─
1030    { rw [to_multiset_zero, multiset.card_zero, sum_zero_index] },
id           └──────────────┘  └────────────────┘  └────────────┘
src      └──┘└──────────────┘└┘└────────────────┘└┘└────────────┘└┘
typ      └──┘└──────────────┘└┘└────────────────┘└┘└────────────┘└┘
doc      └──┘                └┘                  └┘              └┘
txt      └──┘                └┘                  └┘              └┘
par      └──┘                └┘                  └┘              └┘
pid        └┘                └┘                  └┘              
st   ───┘└──────────────────┘└──────────────────┘└──────────────┘└┘
1031    { assume a n f _ _ ih,
src      └─────────────────┘
typ      └─────────────────┘
doc      └─────────────────┘
txt      └─────────────────┘
par      └─────────────────┘
pid      └─────────────────┘
st   ──────────────────────┘└─
1032      rw [to_multiset_add, multiset.card_add, ih, sum_add_index, to_multiset_single,
id           └─────────────┘  └───────────────┘  └┘  └───────────┘  └────────────────┘
src      └──┘└─────────────┘└┘└───────────────┘└┘  └┘└───────────┘└┘└────────────────┘└─
typ      └──┘└─────────────┘└┘└───────────────┘└┘└┘└┘└───────────┘└┘└────────────────┘└─
doc      └──┘               └┘                 └┘  └┘             └┘                  └─
txt      └──┘               └┘                 └┘  └┘             └┘                  └─
par      └──┘               └┘                 └┘  └┘             └┘                  └─
pid        └┘               └┘                 └┘  └┘             └┘                  └─
st   ──────────────────────┘└─────────────────┘└──┘└─────────────┘└──────────────────┘└─
1033        sum_single_index, multiset.card_smul, multiset.singleton_eq_singleton,
id         └──────────────┘  └────────────────┘  └─────────────────────────────┘
src  ─────┘└──────────────┘└┘└────────────────┘└┘└─────────────────────────────┘└─
typ  ─────┘└──────────────┘└┘└────────────────┘└┘└─────────────────────────────┘└─
doc  ─────┘                └┘                  └┘                               └─
txt  ─────┘                └┘                  └┘                               └─
par  ─────┘                └┘                  └┘                               └─
pid  ─────┘                └┘                  └┘                               └─
st   ─────────────────────┘└──────────────────┘└───────────────────────────────┘└─
1034        multiset.card_singleton, mul_one]; intros; refl }
id         └─────────────────────┘  └─────┘
src  ─────┘└─────────────────────┘└┘└─────┘  └────┘  └───┘
typ  ─────┘└─────────────────────┘└┘└─────┘  └────┘  └───┘
doc  ─────┘                       └┘         └────┘  └───┘
txt  ─────┘                       └┘         └────┘  └───┘
par  ─────┘                       └┘         └────┘  └───┘
pid  ─────┘                       └┘                     
st   ────────────────────────────┘└───────┘└─────────────┘└─
1035  end
st   ──┘
1036  
1037  lemma to_multiset_map (f : α →₀ ℕ) (g : α → β) :
id                               └┘           
src                               └┘ 
typ                              └┘           
doc                               └┘
1038    f.to_multiset.map g = (f.map_domain g).to_multiset :=
id     └──────────┘└──┘    └─────────┘  └─────────┘
src     └──────────┘└──┘      └─────────┘   └─────────┘
typ    └──────────┘└──┘    └─────────┘  └─────────┘
doc                 └──┘       └─────────┘
1039  begin
st   └─────
1040    refine f.induction _ _,
id            └─────────┘
src    └─────┘└─────────┘└──┘
typ    └─────┘└─────────┘└──┘
doc    └─────┘           └──┘
txt    └─────┘           └──┘
par    └─────┘           └──┘
pid                     └──┘
st   ───────────────────────┘└─
1041    { rw [to_multiset_zero, multiset.map_zero, map_domain_zero, to_multiset_zero] },
id           └──────────────┘  └───────────────┘  └─────────────┘  └──────────────┘
src      └──┘└──────────────┘└┘└───────────────┘└┘└─────────────┘└┘└──────────────┘└┘
typ      └──┘└──────────────┘└┘└───────────────┘└┘└─────────────┘└┘└──────────────┘└┘
doc      └──┘                └┘                 └┘               └┘                └┘
txt      └──┘                └┘                 └┘               └┘                └┘
par      └──┘                └┘                 └┘               └┘                └┘
pid        └┘                └┘                 └┘               └┘                
st   ───┘└──────────────────┘└─────────────────┘└───────────────┘└────────────────┘└┘
1042    { assume a n f _ _ ih,
src      └─────────────────┘
typ      └─────────────────┘
doc      └─────────────────┘
txt      └─────────────────┘
par      └─────────────────┘
pid      └─────────────────┘
st   ──────────────────────┘└─
1043      rw [to_multiset_add, multiset.map_add, ih, map_domain_add, map_domain_single,
id           └─────────────┘  └──────────────┘  └┘  └────────────┘  └───────────────┘
src      └──┘└─────────────┘└┘└──────────────┘└┘  └┘└────────────┘└┘└───────────────┘└─
typ      └──┘└─────────────┘└┘└──────────────┘└┘└┘└┘└────────────┘└┘└───────────────┘└─
doc      └──┘               └┘                └┘  └┘              └┘                 └─
txt      └──┘               └┘                └┘  └┘              └┘                 └─
par      └──┘               └┘                └┘  └┘              └┘                 └─
pid        └┘               └┘                └┘  └┘              └┘                 └─
st   ──────────────────────┘└────────────────┘└──┘└──────────────┘└─────────────────┘└─
1044        to_multiset_single, to_multiset_add, to_multiset_single,
id         └────────────────┘  └─────────────┘  └────────────────┘
src  ─────┘└────────────────┘└┘└─────────────┘└┘└────────────────┘└─
typ  ─────┘└────────────────┘└┘└─────────────┘└┘└────────────────┘└─
doc  ─────┘                  └┘               └┘                  └─
txt  ─────┘                  └┘               └┘                  └─
par  ─────┘                  └┘               └┘                  └─
pid  ─────┘                  └┘               └┘                  └─
st   ───────────────────────┘└───────────────┘└──────────────────┘└─
1045        is_add_monoid_hom.map_smul (multiset.map g)],
id         └────────────────────────┘  └──────────┘ 
src  ─────┘└────────────────────────┘ └──────────┘ └┘
typ  ─────┘└────────────────────────┘ └──────────┘└┘
doc  ─────┘                           └──────────┘ └┘
txt  ─────┘                                        └┘
par  ─────┘                                        └┘
pid  ─────┘                                        └┘
st   ────────────────────────────────────────────────┘└──
1046      refl }
src      └───┘
typ      └───┘
doc      └───┘
txt      └───┘
par      └───┘
pid          
st   ────────┘└─
1047  end
st   ──┘
1048  
1049  lemma prod_to_multiset [comm_monoid α] (f : α →₀ ℕ) :
id                           └─────────┘         └┘ 
src                          └─────────┘           └┘ 
typ                          └─────────┘         └┘ 
doc                                                └┘
1050    f.to_multiset.prod = f.prod (λa n, a ^ n) :=
id     └──────────┘└───┘  └───┘        
src     └──────────┘└───┘   └───┘          
typ    └──────────┘└───┘  └───┘        
doc                 └───┘    └───┘
1051  begin
st   └─────
1052    refine f.induction _ _,
id            └─────────┘
src    └─────┘└─────────┘└──┘
typ    └─────┘└─────────┘└──┘
doc    └─────┘           └──┘
txt    └─────┘           └──┘
par    └─────┘           └──┘
pid                     └──┘
st   ───────────────────────┘└─
1053    { rw [to_multiset_zero, multiset.prod_zero, finsupp.prod_zero_index] },
id           └──────────────┘  └────────────────┘  └─────────────────────┘
src      └──┘└──────────────┘└┘└────────────────┘└┘└─────────────────────┘└┘
typ      └──┘└──────────────┘└┘└────────────────┘└┘└─────────────────────┘└┘
doc      └──┘                └┘                  └┘                       └┘
txt      └──┘                └┘                  └┘                       └┘
par      └──┘                └┘                  └┘                       └┘
pid        └┘                └┘                  └┘                       
st   ───┘└──────────────────┘└──────────────────┘└───────────────────────┘└┘
1054    { assume a n f _ _ ih,
src      └─────────────────┘
typ      └─────────────────┘
doc      └─────────────────┘
txt      └─────────────────┘
par      └─────────────────┘
pid      └─────────────────┘
st   ──────────────────────┘└─
1055      rw [to_multiset_add, multiset.prod_add, ih, to_multiset_single, finsupp.prod_add_index,
id           └─────────────┘  └───────────────┘  └┘  └────────────────┘  └────────────────────┘
src      └──┘└─────────────┘└┘└───────────────┘└┘  └┘└────────────────┘└┘└────────────────────┘└─
typ      └──┘└─────────────┘└┘└───────────────┘└┘└┘└┘└────────────────┘└┘└────────────────────┘└─
doc      └──┘               └┘                 └┘  └┘                  └┘                      └─
txt      └──┘               └┘                 └┘  └┘                  └┘                      └─
par      └──┘               └┘                 └┘  └┘                  └┘                      └─
pid        └┘               └┘                 └┘  └┘                  └┘                      └─
st   ──────────────────────┘└─────────────────┘└──┘└──────────────────┘└──────────────────────┘└─
1056        finsupp.prod_single_index, multiset.prod_smul, multiset.singleton_eq_singleton,
id         └───────────────────────┘  └────────────────┘  └─────────────────────────────┘
src  ─────┘└───────────────────────┘└┘└────────────────┘└┘└─────────────────────────────┘└─
typ  ─────┘└───────────────────────┘└┘└────────────────┘└┘└─────────────────────────────┘└─
doc  ─────┘                         └┘                  └┘                               └─
txt  ─────┘                         └┘                  └┘                               └─
par  ─────┘                         └┘                  └┘                               └─
pid  ─────┘                         └┘                  └┘                               └─
st   ──────────────────────────────┘└──────────────────┘└───────────────────────────────┘└─
1057        multiset.prod_singleton],
id         └─────────────────────┘
src  ─────┘└─────────────────────┘
typ  ─────┘└─────────────────────┘
doc  ─────┘                       
txt  ─────┘                       
par  ─────┘                       
pid  ─────┘                       
st   ────────────────────────────┘└──
1058      { exact pow_zero a },
id               └──────┘ 
src        └────┘└──────┘ 
typ        └────┘└──────┘
doc        └────┘         
txt        └────┘         
par        └────┘         
pid                      
st   ─────┘└───────────────┘└┘
1059      { exact pow_zero },
id               └──────┘
src        └────┘└──────┘
typ        └────┘└──────┘
doc        └────┘        
txt        └────┘        
par        └────┘        
pid                     
st   ─────┘└─────────────┘└┘
1060      { exact pow_add  } }
id               └─────┘
src        └────┘└─────┘└┘
typ        └────┘└─────┘└┘
doc        └────┘       └┘
txt        └────┘       └┘
par        └────┘       └┘
pid                    └┘
st   ────────────────────┘└───
1061  end
st   ──┘
1062  
1063  lemma to_finset_to_multiset (f : α →₀ ℕ) : f.to_multiset.to_finset = f.support :=
id                                     └┘     └──────────┘└────────┘  └──────┘
src                                     └┘      └──────────┘└────────┘   └──────┘
typ                                    └┘     └──────────┘└────────┘  └──────┘
doc                                     └┘                   └────────┘
1064  begin
st   └─────
1065    refine f.induction _ _,
id            └─────────┘
src    └─────┘└─────────┘└──┘
typ    └─────┘└─────────┘└──┘
doc    └─────┘           └──┘
txt    └─────┘           └──┘
par    └─────┘           └──┘
pid                     └──┘
st   ───────────────────────┘└─
1066    { rw [to_multiset_zero, multiset.to_finset_zero, support_zero] },
id           └──────────────┘  └─────────────────────┘  └──────────┘
src      └──┘└──────────────┘└┘└─────────────────────┘└┘└──────────┘└┘
typ      └──┘└──────────────┘└┘└─────────────────────┘└┘└──────────┘└┘
doc      └──┘                └┘                       └┘            └┘
txt      └──┘                └┘                       └┘            └┘
par      └──┘                └┘                       └┘            └┘
pid        └┘                └┘                       └┘            
st   ───┘└──────────────────┘└───────────────────────┘└────────────┘└┘
1067    { assume a n f ha hn ih,
src      └───────────────────┘
typ      └───────────────────┘
doc      └───────────────────┘
txt      └───────────────────┘
par      └───────────────────┘
pid      └───────────────────┘
st   ────────────────────────┘└─
1068      rw [to_multiset_add, multiset.to_finset_add, ih, to_multiset_single, support_add_eq,
id           └─────────────┘  └────────────────────┘  └┘  └────────────────┘  └────────────┘
src      └──┘└─────────────┘└┘└────────────────────┘└┘  └┘└────────────────┘└┘└────────────┘└─
typ      └──┘└─────────────┘└┘└────────────────────┘└┘└┘└┘└────────────────┘└┘└────────────┘└─
doc      └──┘               └┘                      └┘  └┘                  └┘              └─
txt      └──┘               └┘                      └┘  └┘                  └┘              └─
par      └──┘               └┘                      └┘  └┘                  └┘              └─
pid        └┘               └┘                      └┘  └┘                  └┘              └─
st   ──────────────────────┘└──────────────────────┘└──┘└──────────────────┘└──────────────┘└─
1069        support_single_ne_zero hn, multiset.to_finset_smul _ _ hn,
id         └────────────────────┘ └┘  └─────────────────────┘     └┘
src  ─────┘└────────────────────┘  └┘└─────────────────────┘└───┘  └─
typ  ─────┘└────────────────────┘└┘└┘└─────────────────────┘└───┘└┘└─
doc  ─────┘                        └┘                       └───┘  └─
txt  ─────┘                        └┘                       └───┘  └─
par  ─────┘                        └┘                       └───┘  └─
pid  ─────┘                        └┘                       └───┘  └─
st   ──────────────────────────────┘└──────────────────────────────┘└─
1070        multiset.singleton_eq_singleton, multiset.to_finset_cons, multiset.to_finset_zero],
id         └─────────────────────────────┘  └─────────────────────┘  └─────────────────────┘
src  ─────┘└─────────────────────────────┘└┘└─────────────────────┘└┘└─────────────────────┘
typ  ─────┘└─────────────────────────────┘└┘└─────────────────────┘└┘└─────────────────────┘
doc  ─────┘                               └┘                       └┘                       
txt  ─────┘                               └┘                       └┘                       
par  ─────┘                               └┘                       └┘                       
pid  ─────┘                               └┘                       └┘                       
st   ────────────────────────────────────┘└───────────────────────┘└───────────────────────┘└──
1071      refl,
src      └──┘
typ      └──┘
doc      └──┘
txt      └──┘
par      └──┘
st   ───────┘└─
1072      refine disjoint_mono support_single_subset (subset.refl _) _,
id              └───────────┘ └───────────────────┘  └─────────┘
src      └─────┘└───────────┘└───────────────────┘ └─────────┘└───┘
typ      └─────┘└───────────┘└───────────────────┘ └─────────┘└───┘
doc      └─────┘                                              └───┘
txt      └─────┘                                              └───┘
par      └─────┘                                              └───┘
pid                                                          └───┘
st   ───────────────────────────────────────────────────────────────┘└─
1073      rwa [finset.singleton_eq_singleton, finset.singleton_disjoint] }
id            └───────────────────────────┘  └───────────────────────┘
src      └───┘└───────────────────────────┘└┘└───────────────────────┘└┘
typ      └───┘└───────────────────────────┘└┘└───────────────────────┘└┘
doc      └───┘                             └┘                         └┘
txt      └───┘                             └┘                         └┘
par      └───┘                             └┘                         └┘
pid         └┘                             └┘                         
st   ─────────────────────────────────────┘└─────────────────────────┘└─
1074  end
st   ──┘
1075  
1076  @[simp] lemma count_to_multiset (f : α →₀ ℕ) (a : α) :
id                                         └┘        
src                                         └┘ 
typ                                        └┘        
doc    └──┘                                 └┘
1077    f.to_multiset.count a = f a :=
id     └──────────┘└────┘    
src     └──────────┘└────┘   
typ    └──────────┘└────┘    
doc                 └────┘
1078  calc f.to_multiset.count a = f.sum (λx n, (add_monoid.smul n {x} : multiset α).count a) :
id        └──────────┘└────┘    └──┘       └─────────────┘      └──────┘  └───┘  
src        └──────────┘└────┘      └──┘         └─────────────┘        └──────┘   └───┘
typ       └──────────┘└────┘    └──┘       └─────────────┘      └──────┘  └───┘  
doc                    └────┘      └──┘                                 └──────┘   └───┘
1079      (f.support.sum_hom $ multiset.count a).symm
id        └──────┘└──────┘   └────────────┘  └──┘
src        └──────┘└──────┘   └────────────┘   └──┘
typ       └──────┘└──────┘   └────────────┘  └──┘
doc                           └────────────┘
1080    ... = f.sum (λx n, n * ({x} : multiset α).count a) : by simp only [multiset.count_smul]
id           └──┘             └──────┘  └───┘                    └─────────────────┘
src           └──┘                 └──────┘   └───┘          └─────────┘└─────────────────┘└─
typ          └──┘             └──────┘  └───┘         └─────────┘└─────────────────┘└─
doc           └──┘                   └──────┘   └───┘          └─────────┘                   └─
txt                                                            └─────────┘                   └─
par                                                            └─────────┘                   └─
pid                                                                └──┘└┘                   
st                                                            └────────────────────────────────
1081    ... = f.sum (λx n, n * (x :: 0 : multiset α).count a) : rfl
id           └──┘          └┘     └──────┘  └───┘      └─┘
src  ─┘       └──┘              └┘     └──────┘   └───┘       └─┘
typ  ─┘      └──┘          └┘     └──────┘  └───┘      └─┘
doc  ─┘       └──┘               └┘     └──────┘   └───┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘
1082    ... = f a * (a :: 0 : multiset α).count a : sum_eq_single _
id                └┘     └──────┘  └───┘     └───────────┘
src                  └┘     └──────┘   └───┘      └───────────┘
typ               └┘     └──────┘  └───┘     └───────────┘
doc                   └┘     └──────┘   └───┘
1083      (λ a' _ H, by simp only [multiset.count_cons_of_ne (ne.symm H), multiset.count_zero, mul_zero])
id          └┘                  └───────────────────────┘  └─────┘    └─────────────────┘  └──────┘
src                    └─────────┘└───────────────────────┘ └─────┘ └─┘└─────────────────┘└┘└──────┘
typ         └┘       └─────────┘└───────────────────────┘ └─────┘└─┘└─────────────────┘└┘└──────┘
doc                    └─────────┘                                  └─┘                   └┘        
txt                    └─────────┘                                  └─┘                   └┘        
par                    └─────────┘                                  └─┘                   └┘        
pid                        └──┘└┘                                  └─┘                   └┘        
st                    └───────────────────────────────────────────────────────────────────────────────┘
1084      (λ H, by simp only [not_mem_support_iff.1 H, zero_mul])
id                          └─────────────────┘     └──────┘
src               └─────────┘└─────────────────┘└─┘ └┘└──────┘
typ              └─────────┘└─────────────────┘└─┘└┘└──────┘
doc               └─────────┘                   └─┘ └┘        
txt               └─────────┘                   └─┘ └┘        
par               └─────────┘                   └─┘ └┘        
pid                   └──┘└┘                   └─┘ └┘        
st               └────────────────────────────────────────────┘
1085    ... = f a : by simp only [multiset.count_singleton, mul_one]
id                             └──────────────────────┘  └─────┘
src                   └─────────┘└──────────────────────┘└┘└─────┘└─
typ                 └─────────┘└──────────────────────┘└┘└─────┘└─
doc                   └─────────┘                        └┘       └─
txt                   └─────────┘                        └┘       └─
par                   └─────────┘                        └┘       └─
pid                       └──┘└┘                        └┘       
st                   └──────────────────────────────────────────────
1086  
src  
typ  
doc  
txt  
par  
pid  
st   
1087  def of_multiset (m : multiset α) : α →₀ ℕ :=
id                        └──────┘      └┘ 
src                       └──────┘        └┘ 
typ                       └──────┘      └┘ 
doc                       └──────┘        └┘
1088  on_finset m.to_finset (λa, m.count a) $ λ a H, multiset.mem_to_finset.2 $
id   └───────┘ └────────┘     └────┘          └────────────────────┘
src  └───────┘  └────────┘       └────┘             └────────────────────┘
typ  └───────┘ └────────┘     └────┘          └────────────────────┘
doc  └───────┘  └────────┘       └────┘
1089  by_contradiction (mt multiset.count_eq_zero.2 H)
id   └──────────────┘  └┘ └────────────────────┘  
src  └──────────────┘  └┘ └────────────────────┘
typ  └──────────────┘  └┘ └────────────────────┘  
1090  
1091  @[simp] lemma of_multiset_apply (m : multiset α) (a : α) :
id                                        └──────┘        
src                                       └──────┘
typ                                       └──────┘        
doc    └──┘                               └──────┘
1092    of_multiset m a = m.count a :=
id     └─────────┘    └────┘ 
src    └─────────┘       └────┘
typ    └─────────┘    └────┘ 
doc                       └────┘
1093  rfl
id   └─┘
src  └─┘
typ  └─┘
1094  
1095  def equiv_multiset : (α →₀ ℕ) ≃ (multiset α) :=
id                          └┘     └──────┘ 
src                          └┘     └──────┘
typ                         └┘     └──────┘ 
doc                          └┘      └──────┘
1096  ⟨ to_multiset, of_multiset,
id     └─────────┘  └─────────┘
src    └─────────┘  └─────────┘
typ    └─────────┘  └─────────┘
1097  assume f, finsupp.ext $ λ a, by rw [of_multiset_apply, count_to_multiset],
id            └─────────┘              └───────────────┘  └───────────────┘
src            └─────────┘           └──┘└───────────────┘└┘└───────────────┘
typ           └─────────┘          └──┘└───────────────┘└┘└───────────────┘
doc                                  └──┘                 └┘                 
txt                                  └──┘                 └┘                 
par                                  └──┘                 └┘                 
pid                                    └┘                 └┘                 
st                                  └────────────────────┘└─────────────────┘
1098  assume m, multiset.ext.2 $ λ a, by rw [count_to_multiset, of_multiset_apply] ⟩
id            └──────────┘               └───────────────┘  └───────────────┘
src            └──────────┘            └──┘└───────────────┘└┘└───────────────┘└┘
typ           └──────────┘           └──┘└───────────────┘└┘└───────────────┘└┘
doc                                     └──┘                 └┘                 └┘
txt                                     └──┘                 └┘                 └┘
par                                     └──┘                 └┘                 └┘
pid                                       └┘                 └┘                 
st                                     └────────────────────┘└─────────────────┘
1099  
1100  lemma mem_support_multiset_sum [add_comm_monoid β]
id                                   └─────────────┘ 
src                                  └─────────────┘
typ                                  └─────────────┘ 
1101    {s : multiset (α →₀ β)} (a : α) :
id          └──────┘   └┘         
src         └──────┘    └┘
typ         └──────┘   └┘         
doc         └──────┘    └┘
1102    a ∈ s.sum.support → ∃f∈s, a ∈ (f : α →₀ β).support :=
id       └──┘└──────┘            └┘  └─────┘
src        └──┘└──────┘                 └┘   └─────┘
typ      └──┘└──────┘            └┘  └─────┘
doc                                         └┘
1103  multiset.induction_on s false.elim
id   └───────────────────┘  └────────┘
src  └───────────────────┘   └────────┘
typ  └───────────────────┘  └────────┘
1104    begin
st     └─────
1105      assume f s ih ha,
src      └──────────────┘
typ      └──────────────┘
doc      └──────────────┘
txt      └──────────────┘
par      └──────────────┘
pid      └──────────────┘
st   ───────────────────┘└─
1106      by_cases a ∈ f.support,
id                  └───────┘
src      └───────┘ └───────┘
typ      └───────┘└───────┘
doc      └───────┘  
txt      └───────┘  
par      └───────┘  
pid                
st   ─────────────────────────┘└─
1107      { exact ⟨f, multiset.mem_cons_self _ _, h⟩ },
id                  └────────────────────┘      
src        └────┘  └┘└────────────────────┘└────┘ └┘
typ        └────┘ └┘└────────────────────┘└────┘└┘
doc        └────┘  └┘                      └────┘ └┘
txt        └────┘  └┘                      └────┘ └┘
par        └────┘  └┘                      └────┘ └┘
pid               └┘                      └────┘ 
st   ─────┘└───────────────────────────────────────┘└┘
1108      { simp only [multiset.sum_cons, mem_support_iff, add_apply,
id                    └───────────────┘  └─────────────┘  └───────┘
src        └─────────┘└───────────────┘└┘└─────────────┘└┘└───────┘└─
typ        └─────────┘└───────────────┘└┘└─────────────┘└┘└───────┘└─
doc        └─────────┘                 └┘               └┘         └─
txt        └─────────┘                 └┘               └┘         └─
par        └─────────┘                 └┘               └┘         └─
pid            └──┘└┘                 └┘               └┘         └─
st   ────────────────────────────────────────────────────────────────
1109          not_mem_support_iff.1 h, zero_add] at ha,
id           └─────────────────┘     └──────┘
src  ───────┘└─────────────────┘└─┘ └┘└──────┘└─────┘
typ  ───────┘└─────────────────┘└─┘└┘└──────┘└─────┘
doc  ───────┘                   └─┘ └┘        └─────┘
txt  ───────┘                   └─┘ └┘        └─────┘
par  ───────┘                   └─┘ └┘        └─────┘
pid  ───────┘                   └─┘ └┘        └───┘
st   ───────────────────────────────────────────────┘└─
1110        rcases ih (mem_support_iff.2 ha) with ⟨f', h₀, h₁⟩,
id                └┘  └─────────────┘   └┘
src        └─────┘   └─────────────┘└─┘  └─────────────────┘
typ        └─────┘└┘ └─────────────┘└─┘└┘└─────────────────┘
doc        └─────┘                  └─┘  └─────────────────┘
txt        └─────┘                  └─┘  └─────────────────┘
par        └─────┘                  └─┘  └─────────────────┘
pid                                └─┘  └─────────────────┘
st   ───────────────────────────────────────────────────────┘└─
1111        exact ⟨f', multiset.mem_cons_of_mem h₀, h₁⟩ }
id                └┘  └──────────────────────┘ └┘  └┘
src        └────┘   └┘└──────────────────────┘  └┘  └┘
typ        └────┘ └┘└┘└──────────────────────┘└┘└┘└┘└┘
doc        └────┘   └┘                          └┘  └┘
txt        └────┘   └┘                          └┘  └┘
par        └────┘   └┘                          └┘  └┘
pid                └┘                          └┘  
st   ─────────────────────────────────────────────────┘└─
1112    end
st   ────┘
1113  
1114  lemma mem_support_finset_sum [add_comm_monoid β]
id                                 └─────────────┘ 
src                                └─────────────┘
typ                                └─────────────┘ 
1115    {s : finset γ} {h : γ → α →₀ β} (a : α) (ha : a ∈ (s.sum h).support) : ∃c∈s, a ∈ (h c).support :=
id          └────┘            └┘                   └──┘  └─────┘            └─────┘
src         └────┘               └┘                       └──┘   └─────┘                 └─────┘
typ         └────┘            └┘                   └──┘  └─────┘            └─────┘
doc         └────┘               └┘
1116  let ⟨f, hf, hfa⟩ := mem_support_multiset_sum a ha in
id   └─┘     └┘  └─┘     └──────────────────────┘  └┘
src                      └──────────────────────┘
typ  └─┘     └┘  └─┘     └──────────────────────┘  └┘
1117  let ⟨c, hc, eq⟩ := multiset.mem_map.1 hf in
id   └─┘    └┘  └┘     └──────────────┘
src              └┘     └──────────────┘
typ  └─┘    └┘  └┘     └──────────────┘
1118  ⟨c, hc, eq.symm ▸ hfa⟩
id             └───┘ 
src            └───┘ 
typ            └───┘ 
1119  
1120  lemma mem_support_single [has_zero β] (a a' : α) (b : β) :
id                             └──────┘                  
src                            └──────┘
typ                            └──────┘                  
1121    a ∈ (single a' b).support ↔ a = a' ∧ b ≠ 0 :=
id        └────┘ └┘  └─────┘     └┘   
src        └────┘      └─────┘            
typ       └────┘ └┘  └─────┘     └┘   
doc         └────┘
1122  ⟨λ H : (a ∈ ite _ _ _), if h : b = 0
id             └─┘         └┘      
src             └─┘         └┘       
typ            └─┘         └┘      
1123    then by rw if_pos h at H; exact H.elim
id                └────┘              └────┘
src            └─┘└────┘ └───┘  └────┘└────┘
typ            └─┘└────┘└───┘  └────┘└────┘
doc            └─┘       └───┘  └────┘      
txt            └─┘       └───┘  └────┘      
par            └─┘       └───┘  └────┘      
pid                     └───┘             
st            └───────────────────────────────
1124    else ⟨by rw if_neg h at H; exact mem_singleton.1 H, h⟩,
id                └────┘              └───────────┘     
src  ─┘         └─┘└────┘ └───┘  └────┘└───────────┘└─┘
typ  ─┘        └─┘└────┘└───┘  └────┘└───────────┘└─┘  
doc  ─┘         └─┘       └───┘  └────┘             └─┘
txt  ─┘         └─┘       └───┘  └────┘             └─┘
par  ─┘         └─┘       └───┘  └────┘             └─┘
pid  ─┘                  └───┘                    └─┘
st   ─┘        └────────────────────────────────────────┘
1125  λ ⟨h1, h2⟩, show a ∈ ite _ _ _, by rw [if_neg h2]; exact mem_singleton.2 h1⟩
id                     └─┘               └────┘ └┘         └───────────┘   └┘
src                      └─┘           └──┘└────┘    └────┘└───────────┘└─┘
typ                    └─┘           └──┘└────┘└┘  └────┘└───────────┘└─┘└┘
doc                                     └──┘          └────┘             └─┘
txt                                     └──┘          └────┘             └─┘
par                                     └──┘          └────┘             └─┘
pid                                       └┘                            └─┘
st                                     └────────────┘└────────────────────────┘
1126  
1127  end multiset
1128  
1129  section curry_uncurry
1130  
1131  protected def curry [add_comm_monoid γ]
id                        └─────────────┘ 
src                       └─────────────┘
typ                       └─────────────┘ 
1132    (f : (α × β) →₀ γ) : α →₀ (β →₀ γ) :=
id               └┘      └┘   └┘ 
src                └┘        └┘    └┘
typ              └┘      └┘   └┘ 
doc                 └┘        └┘    └┘
1133  f.sum $ λp c, single p.1 (single p.2 c)
id   └──┘       └────┘    └────┘   
src   └──┘         └────┘     └────┘  
typ  └──┘       └────┘    └────┘   
doc   └──┘         └────┘      └────┘
1134  
1135  lemma sum_curry_index
1136    [add_comm_monoid γ] [add_comm_monoid δ]
id      └─────────────┘    └─────────────┘ 
src     └─────────────┘     └─────────────┘
typ     └─────────────┘    └─────────────┘ 
1137    (f : (α × β) →₀ γ) (g : α → β → γ → δ)
id               └┘                 
src                └┘
typ              └┘                 
doc                 └┘
1138    (hg₀ : ∀ a b, g a b 0 = 0) (hg₁ : ∀a b c₀ c₁, g a b (c₀ + c₁) = g a b c₀ + g a b c₁) :
id                                    └┘ └┘      └┘  └┘      └┘     └┘
src                                                                          
typ                                   └┘ └┘      └┘  └┘      └┘     └┘
1139    f.curry.sum (λa f, f.sum (g a)) = f.sum (λp c, g p.1 p.2 c) :=
id     └────┘└──┘      └──┘       └──┘           
src     └────┘└──┘         └──┘          └──┘              
typ    └────┘└──┘      └──┘       └──┘           
doc           └──┘         └──┘           └──┘
1140  begin
st   └─────
1141    rw [finsupp.curry],
id         └───────────┘
src    └──┘└───────────┘
typ    └──┘└───────────┘
doc    └──┘             
txt    └──┘             
par    └──┘             
pid      └┘             
st   ──────────────────┘└──
1142    transitivity,
src    └──────────┘
typ    └──────────┘
doc    └──────────┘
txt    └──────────┘
par    └──────────┘
st   ─────────────┘└─
1143    { exact sum_sum_index (assume a, sum_zero_index)
id             └───────────┘            └────────────┘
src      └────┘└───────────┘       └──┘└────────────┘└─
typ      └────┘└───────────┘       └──┘└────────────┘└─
doc      └────┘                    └──┘              └─
txt      └────┘                    └──┘              └─
par      └────┘                    └──┘              └─
pid                               └──┘              └─
st   ───┘└──────────────────────────────────────────────
1144        (assume a b₀ b₁, sum_add_index (assume a, hg₀ _ _) (assume c d₀ d₁, hg₁ _ _ _ _)) },
id                          └───────────┘            └─┘                       └─┘
src  ─────┘       └────────┘└───────────┘       └──┘   └────┘       └────────┘   └─────────┘
typ  ─────┘       └────────┘└───────────┘       └──┘└─┘└────┘       └────────┘└─┘└─────────┘
doc  ─────┘       └────────┘                    └──┘   └────┘       └────────┘   └─────────┘
txt  ─────┘       └────────┘                    └──┘   └────┘       └────────┘   └─────────┘
par  ─────┘       └────────┘                    └──┘   └────┘       └────────┘   └─────────┘
pid  ─────┘       └────────┘                    └──┘   └────┘       └────────┘   └────────┘
st   ───────────────────────────────────────────────────────────────────────────────────────┘└┘
1145    congr, funext p c,
src    └───┘  └────────┘
typ    └───┘  └────────┘
doc           └────────┘
txt    └───┘  └────────┘
par    └───┘  └────────┘
pid                 └──┘
st   ──────┘└──────────┘└─
1146    transitivity,
src    └──────────┘
typ    └──────────┘
doc    └──────────┘
txt    └──────────┘
par    └──────────┘
st   ─────────────┘└─
1147    { exact sum_single_index sum_zero_index },
id             └──────────────┘ └────────────┘
src      └────┘└──────────────┘└────────────┘
typ      └────┘└──────────────┘└────────────┘
doc      └────┘                              
txt      └────┘                              
par      └────┘                              
pid                                         
st   ───┘└────────────────────────────────────┘└┘
1148    exact sum_single_index (hg₀ _ _)
id           └──────────────┘  └─┘
src    └────┘└──────────────┘    └────┘
typ    └────┘└──────────────┘ └─┘└────┘
doc    └────┘                    └────┘
txt    └────┘                    └────┘
par    └────┘                    └────┘
pid                             └───┘
st   ──────────────────────────────────┘
1149  end
st   └─┘
1150  
1151  protected def uncurry [add_comm_monoid γ] (f : α →₀ (β →₀ γ)) : (α × β) →₀ γ :=
id                          └─────────────┘         └┘   └┘           └┘ 
src                         └─────────────┘           └┘    └┘              └┘
typ                         └─────────────┘         └┘   └┘           └┘ 
doc                                                   └┘    └┘               └┘
1152  f.sum $ λa g, g.sum $ λb c, single (a, b) c
id   └──┘       └──┘       └────┘     
src   └──┘          └──┘         └────┘ 
typ  └──┘       └──┘       └────┘     
doc   └──┘          └──┘         └────┘
1153  
1154  def finsupp_prod_equiv [add_comm_monoid γ] : ((α × β) →₀ γ) ≃ (α →₀ (β →₀ γ)) :=
id                           └─────────────┘           └┘      └┘   └┘ 
src                          └─────────────┘              └┘        └┘    └┘
typ                          └─────────────┘           └┘      └┘   └┘ 
doc                                                        └┘        └┘    └┘
1155  by refine ⟨finsupp.curry, finsupp.uncurry, λ f, _, λ f, _⟩; simp only [
id              └───────────┘  └─────────────┘
src     └─────┘ └───────────┘└┘└─────────────┘└┘ └─────┘ └────┘  └───────────
typ     └─────┘ └───────────┘└┘└─────────────┘└┘ └─────┘ └────┘  └───────────
doc     └─────┘              └┘               └┘ └─────┘ └────┘  └───────────
txt     └─────┘              └┘               └┘ └─────┘ └────┘  └───────────
par     └─────┘              └┘               └┘ └─────┘ └────┘  └───────────
pid                         └┘               └┘ └─────┘ └────┘      └──┘└──
st     └─────────────────────────────────────────────────────────────────────
1156    finsupp.curry, finsupp.uncurry, sum_sum_index, sum_zero_index, sum_add_index,
id     └───────────┘  └─────────────┘  └───────────┘  └────────────┘  └───────────┘
src  ─┘└───────────┘└┘└─────────────┘└┘└───────────┘└┘└────────────┘└┘└───────────┘└─
typ  ─┘└───────────┘└┘└─────────────┘└┘└───────────┘└┘└────────────┘└┘└───────────┘└─
doc  ─┘             └┘               └┘             └┘              └┘             └─
txt  ─┘             └┘               └┘             └┘              └┘             └─
par  ─┘             └┘               └┘             └┘              └┘             └─
pid  ─┘             └┘               └┘             └┘              └┘             └─
st   ────────────────────────────────────────────────────────────────────────────────
1157    sum_single_index, single_zero, single_add, eq_self_iff_true, forall_true_iff,
id     └──────────────┘  └─────────┘  └────────┘  └──────────────┘  └─────────────┘
src  ─┘└──────────────┘└┘└─────────┘└┘└────────┘└┘└──────────────┘└┘└─────────────┘└─
typ  ─┘└──────────────┘└┘└─────────┘└┘└────────┘└┘└──────────────┘└┘└─────────────┘└─
doc  ─┘                └┘           └┘          └┘                └┘               └─
txt  ─┘                └┘           └┘          └┘                └┘               └─
par  ─┘                └┘           └┘          └┘                └┘               └─
pid  ─┘                └┘           └┘          └┘                └┘               └─
st   ────────────────────────────────────────────────────────────────────────────────
1158    forall_3_true_iff, prod.mk.eta, (single_sum _ _ _).symm, sum_single]
id     └───────────────┘  └─────────┘   └────────┘              └────────┘
src  ─┘└───────────────┘└┘└─────────┘└┘ └────────┘└────────────┘└────────┘└─
typ  ─┘└───────────────┘└┘└─────────┘└┘ └────────┘└────────────┘└────────┘└─
doc  ─┘                 └┘           └┘           └────────────┘          └─
txt  ─┘                 └┘           └┘           └────────────┘          └─
par  ─┘                 └┘           └┘           └────────────┘          └─
pid  ─┘                 └┘           └┘           └────────────┘          
st   ───────────────────────────────────────────────────────────────────────
1159  
src  
typ  
doc  
txt  
par  
pid  
st   
1160  lemma filter_curry [add_comm_monoid β] (f : α₁ × α₂ →₀ β) (p : α₁ → Prop) :
id                       └─────────────┘        └┘  └┘ └┘        └┘
src                      └─────────────┘                └┘
typ                      └─────────────┘        └┘  └┘ └┘        └┘
doc                                                      └┘
1161    (f.filter (λa:α₁×α₂, p a.1)).curry = f.curry.filter p :=
id      └─────┘     └┘└┘      └───┘   └────┘└─────┘ 
src      └─────┘                 └───┘    └────┘└─────┘
typ     └─────┘     └┘└┘      └───┘   └────┘└─────┘ 
doc      └─────┘                                   └─────┘
1162  begin
st   └─────
1163    rw [finsupp.curry, finsupp.curry, finsupp.sum, finsupp.sum,
id         └───────────┘  └───────────┘  └─────────┘  └─────────┘
src    └──┘└───────────┘└┘└───────────┘└┘└─────────┘└┘└─────────┘└─
typ    └──┘└───────────┘└┘└───────────┘└┘└─────────┘└┘└─────────┘└─
doc    └──┘             └┘             └┘└─────────┘└┘└─────────┘└─
txt    └──┘             └┘             └┘           └┘           └─
par    └──┘             └┘             └┘           └┘           └─
pid      └┘             └┘             └┘           └┘           └─
st   ──────────────────┘└─────────────┘└───────────┘└───────────┘└─
1164      @filter_sum _ (α₂ →₀ β) _ p _ f.support _],
id        └────────┘    └┘ └┘        └───────┘
src  ───┘ └────────┘└─┘   └┘ └──┘ └─┘└───────┘└─┘
typ  ───┘ └────────┘└─┘ └┘└┘└──┘└─┘└───────┘└─┘
doc  ───┘           └─┘   └┘ └──┘ └─┘         └─┘
txt  ───┘           └─┘      └──┘ └─┘         └─┘
par  ───┘           └─┘      └──┘ └─┘         └─┘
pid  ───┘           └─┘      └──┘ └─┘         └─┘
st   ────────────────────────────────────────────┘└──
1165    rw [support_filter, sum_filter],
id         └────────────┘  └────────┘
src    └──┘└────────────┘└┘└────────┘
typ    └──┘└────────────┘└┘└────────┘
doc    └──┘              └┘          
txt    └──┘              └┘          
par    └──┘              └┘          
pid      └┘              └┘          
st   ───────────────────┘└──────────┘└──
1166    refine finset.sum_congr rfl _,
id            └──────────────┘ └─┘
src    └─────┘└──────────────┘└─┘└┘
typ    └─────┘└──────────────┘└─┘└┘
doc    └─────┘                   └┘
txt    └─────┘                   └┘
par    └─────┘                   └┘
pid                             └┘
st   ──────────────────────────────┘└─
1167    rintros ⟨a₁, a₂⟩ ha,
src    └─────────────────┘
typ    └─────────────────┘
doc    └─────────────────┘
txt    └─────────────────┘
par    └─────────────────┘
pid           └──────────┘
st   ────────────────────┘└─
1168    dsimp only,
src    └────────┘
typ    └────────┘
doc    └────────┘
txt    └────────┘
par    └────────┘
pid         └───┘
st   ───────────┘└─
1169    split_ifs,
src    └───────┘
typ    └───────┘
doc    └───────┘
txt    └───────┘
par    └───────┘
st   ──────────┘└─
1170    { rw [filter_apply_pos, filter_single_of_pos]; exact h },
id           └──────────────┘  └──────────────────┘         
src      └──┘└──────────────┘└┘└──────────────────┘  └────┘ 
typ      └──┘└──────────────┘└┘└──────────────────┘  └────┘
doc      └──┘                └┘                      └────┘ 
txt      └──┘                └┘                      └────┘ 
par      └──┘                └┘                      └────┘ 
pid        └┘                └┘                            
st   ───┘└──────────────────┘└────────────────────┘└────────┘└┘
1171    { rwa [filter_single_of_neg] }
id            └──────────────────┘
src      └───┘└──────────────────┘└┘
typ      └───┘└──────────────────┘└┘
doc      └───┘                    └┘
txt      └───┘                    └┘
par      └───┘                    └┘
pid         └┘                    
st   ────────────────────────────┘└─
1172  end
st   ──┘
1173  
1174  lemma support_curry [add_comm_monoid β] (f : α₁ × α₂ →₀ β) :
id                        └─────────────┘        └┘  └┘ └┘ 
src                       └─────────────┘                └┘
typ                       └─────────────┘        └┘  └┘ └┘ 
doc                                                       └┘
1175    f.curry.support ⊆ f.support.image prod.fst :=
id     └────┘└──────┘  └──────┘└────┘ └──────┘
src     └────┘└──────┘   └──────┘└────┘ └──────┘
typ    └────┘└──────┘  └──────┘└────┘ └──────┘
doc                               └────┘
1176  begin
st   └─────
1177    rw ← finset.bind_singleton,
id          └───────────────────┘
src    └───┘└───────────────────┘
typ    └───┘└───────────────────┘
doc    └───┘
txt    └───┘
par    └───┘
pid      └─┘
st   ───────────────────────────┘└─
1178    refine finset.subset.trans support_sum _,
id            └─────────────────┘ └─────────┘
src    └─────┘└─────────────────┘└─────────┘└┘
typ    └─────┘└─────────────────┘└─────────┘└┘
doc    └─────┘                              └┘
txt    └─────┘                              └┘
par    └─────┘                              └┘
pid                                        └┘
st   ─────────────────────────────────────────┘└─
1179    refine finset.bind_mono (assume a _, support_single_subset)
id            └──────────────┘              └───────────────────┘
src    └─────┘└──────────────┘       └────┘└───────────────────┘└┘
typ    └─────┘└──────────────┘       └────┘└───────────────────┘└┘
doc    └─────┘                       └────┘                     └┘
txt    └─────┘                       └────┘                     └┘
par    └─────┘                       └────┘                     └┘
pid                                 └────┘                     
st   ─────────────────────────────────────────────────────────────┘
1180  end
st   └─┘
1181  
1182  end curry_uncurry
1183  
1184  section
1185  variables [add_monoid α] [semiring β]
id              └────────┘     └──────┘
src             └────────┘     └──────┘
typ             └────────┘     └──────┘
1186  
1187  -- TODO: the simplifier unfolds 0 in the instance proof!
1188  private lemma zero_mul (f : α →₀ β) : 0 * f = 0 := by simp only [mul_def, sum_zero_index]
id                                └┘                             └─────┘  └────────────┘
src                                └┘                    └─────────┘└─────┘└┘└────────────┘└┘
typ                               └┘                  └─────────┘└─────┘└┘└────────────┘└┘
doc                                └┘                      └─────────┘       └┘              └┘
txt                                                        └─────────┘       └┘              └┘
par                                                        └─────────┘       └┘              └┘
pid                                                            └──┘└┘       └┘              
st                                                        └───────────────────────────────────┘
1189  private lemma mul_zero (f : α →₀ β) : f * 0 = 0 := by simp only [mul_def, sum_zero_index, sum_zero]
id                                └┘                             └─────┘  └────────────┘  └──────┘
src                                └┘                    └─────────┘└─────┘└┘└────────────┘└┘└──────┘└┘
typ                               └┘                  └─────────┘└─────┘└┘└────────────┘└┘└──────┘└┘
doc                                └┘                      └─────────┘       └┘              └┘        └┘
txt                                                        └─────────┘       └┘              └┘        └┘
par                                                        └─────────┘       └┘              └┘        └┘
pid                                                            └──┘└┘       └┘              └┘        
st                                                        └─────────────────────────────────────────────┘
1190  private lemma left_distrib (a b c : α →₀ β) : a * (b + c) = a * b + a * c :=
id                                        └┘                   
src                                        └┘                         
typ                                       └┘                   
doc                                        └┘
1191  by simp only [mul_def, sum_add_index, mul_add, _root_.mul_zero, single_zero, single_add,
id                 └─────┘  └───────────┘  └─────┘  └─────────────┘  └─────────┘  └────────┘
src     └─────────┘└─────┘└┘└───────────┘└┘└─────┘└┘└─────────────┘└┘└─────────┘└┘└────────┘└─
typ     └─────────┘└─────┘└┘└───────────┘└┘└─────┘└┘└─────────────┘└┘└─────────┘└┘└────────┘└─
doc     └─────────┘       └┘             └┘       └┘               └┘           └┘          └─
txt     └─────────┘       └┘             └┘       └┘               └┘           └┘          └─
par     └─────────┘       └┘             └┘       └┘               └┘           └┘          └─
pid         └──┘└┘       └┘             └┘       └┘               └┘           └┘          └─
st     └──────────────────────────────────────────────────────────────────────────────────────
1192    eq_self_iff_true, forall_true_iff, forall_3_true_iff, sum_add]
id     └──────────────┘  └─────────────┘  └───────────────┘  └─────┘
src  ─┘└──────────────┘└┘└─────────────┘└┘└───────────────┘└┘└─────┘└┘
typ  ─┘└──────────────┘└┘└─────────────┘└┘└───────────────┘└┘└─────┘└┘
doc  ─┘                └┘               └┘                 └┘       └┘
txt  ─┘                └┘               └┘                 └┘       └┘
par  ─┘                └┘               └┘                 └┘       └┘
pid  ─┘                └┘               └┘                 └┘       
st   ────────────────────────────────────────────────────────────────┘
1193  private lemma right_distrib (a b c : α →₀ β) : (a + b) * c = a * c + b * c :=
id                                         └┘                   
src                                         └┘                         
typ                                        └┘                   
doc                                         └┘
1194  by simp only [mul_def, sum_add_index, add_mul, _root_.mul_zero, _root_.zero_mul, single_zero, single_add,
id                 └─────┘  └───────────┘  └─────┘  └─────────────┘  └─────────────┘  └─────────┘  └────────┘
src     └─────────┘└─────┘└┘└───────────┘└┘└─────┘└┘└─────────────┘└┘└─────────────┘└┘└─────────┘└┘└────────┘└─
typ     └─────────┘└─────┘└┘└───────────┘└┘└─────┘└┘└─────────────┘└┘└─────────────┘└┘└─────────┘└┘└────────┘└─
doc     └─────────┘       └┘             └┘       └┘               └┘               └┘           └┘          └─
txt     └─────────┘       └┘             └┘       └┘               └┘               └┘           └┘          └─
par     └─────────┘       └┘             └┘       └┘               └┘               └┘           └┘          └─
pid         └──┘└┘       └┘             └┘       └┘               └┘               └┘           └┘          └─
st     └───────────────────────────────────────────────────────────────────────────────────────────────────────
1195    eq_self_iff_true, forall_true_iff, forall_3_true_iff, sum_zero, sum_add]
id     └──────────────┘  └─────────────┘  └───────────────┘  └──────┘  └─────┘
src  ─┘└──────────────┘└┘└─────────────┘└┘└───────────────┘└┘└──────┘└┘└─────┘└─
typ  ─┘└──────────────┘└┘└─────────────┘└┘└───────────────┘└┘└──────┘└┘└─────┘└─
doc  ─┘                └┘               └┘                 └┘        └┘       └─
txt  ─┘                └┘               └┘                 └┘        └┘       └─
par  ─┘                └┘               └┘                 └┘        └┘       └─
pid  ─┘                └┘               └┘                 └┘        └┘       
st   ───────────────────────────────────────────────────────────────────────────
1196  
src  
typ  
doc  
txt  
par  
pid  
st   
1197  instance : semiring (α →₀ β) :=
id              └──────┘   └┘ 
src             └──────┘    └┘
typ             └──────┘   └┘ 
doc                         └┘
1198  { one       := 1,
1199    mul       := (*),
id                  
src                 
typ                 
1200    one_mul   := assume f, by simp only [mul_def, one_def, sum_single_index, _root_.zero_mul, single_zero, sum_zero,
id                                         └─────┘  └─────┘  └──────────────┘  └─────────────┘  └─────────┘  └──────┘
src                              └─────────┘└─────┘└┘└─────┘└┘└──────────────┘└┘└─────────────┘└┘└─────────┘└┘└──────┘└─
typ                             └─────────┘└─────┘└┘└─────┘└┘└──────────────┘└┘└─────────────┘└┘└─────────┘└┘└──────┘└─
doc                              └─────────┘       └┘       └┘                └┘               └┘           └┘        └─
txt                              └─────────┘       └┘       └┘                └┘               └┘           └┘        └─
par                              └─────────┘       └┘       └┘                └┘               └┘           └┘        └─
pid                                  └──┘└┘       └┘       └┘                └┘               └┘           └┘        └─
st                              └───────────────────────────────────────────────────────────────────────────────────────
1201      zero_add, one_mul, sum_single],
id       └──────┘  └─────┘  └────────┘
src  ───┘└──────┘└┘└─────┘└┘└────────┘
typ  ───┘└──────┘└┘└─────┘└┘└────────┘
doc  ───┘        └┘       └┘          
txt  ───┘        └┘       └┘          
par  ───┘        └┘       └┘          
pid  ───┘        └┘       └┘          
st   ─────────────────────────────────┘
1202    mul_one   := assume f, by simp only [mul_def, one_def, sum_single_index, _root_.mul_zero, single_zero, sum_zero,
id                                         └─────┘  └─────┘  └──────────────┘  └─────────────┘  └─────────┘  └──────┘
src                              └─────────┘└─────┘└┘└─────┘└┘└──────────────┘└┘└─────────────┘└┘└─────────┘└┘└──────┘└─
typ                             └─────────┘└─────┘└┘└─────┘└┘└──────────────┘└┘└─────────────┘└┘└─────────┘└┘└──────┘└─
doc                              └─────────┘       └┘       └┘                └┘               └┘           └┘        └─
txt                              └─────────┘       └┘       └┘                └┘               └┘           └┘        └─
par                              └─────────┘       └┘       └┘                └┘               └┘           └┘        └─
pid                                  └──┘└┘       └┘       └┘                └┘               └┘           └┘        └─
st                              └───────────────────────────────────────────────────────────────────────────────────────
1203      add_zero, mul_one, sum_single],
id       └──────┘  └─────┘  └────────┘
src  ───┘└──────┘└┘└─────┘└┘└────────┘
typ  ───┘└──────┘└┘└─────┘└┘└────────┘
doc  ───┘        └┘       └┘          
txt  ───┘        └┘       └┘          
par  ───┘        └┘       └┘          
pid  ───┘        └┘       └┘          
st   ─────────────────────────────────┘
1204    zero_mul  := zero_mul,
id                  └──────┘
src                 └──────┘
typ                 └──────┘
1205    mul_zero  := mul_zero,
id                  └──────┘
src                 └──────┘
typ                 └──────┘
1206    mul_assoc := assume f g h, by simp only [mul_def, sum_sum_index, sum_zero_index, sum_add_index, sum_single_index,
id                                           └─────┘  └───────────┘  └────────────┘  └───────────┘  └──────────────┘
src                                  └─────────┘└─────┘└┘└───────────┘└┘└────────────┘└┘└───────────┘└┘└──────────────┘└─
typ                               └─────────┘└─────┘└┘└───────────┘└┘└────────────┘└┘└───────────┘└┘└──────────────┘└─
doc                                  └─────────┘       └┘             └┘              └┘             └┘                └─
txt                                  └─────────┘       └┘             └┘              └┘             └┘                └─
par                                  └─────────┘       └┘             └┘              └┘             └┘                └─
pid                                      └──┘└┘       └┘             └┘              └┘             └┘                └─
st                                  └────────────────────────────────────────────────────────────────────────────────────
1207      single_zero, single_add, eq_self_iff_true, forall_true_iff, forall_3_true_iff,
id       └─────────┘  └────────┘  └──────────────┘  └─────────────┘  └───────────────┘
src  ───┘└─────────┘└┘└────────┘└┘└──────────────┘└┘└─────────────┘└┘└───────────────┘└─
typ  ───┘└─────────┘└┘└────────┘└┘└──────────────┘└┘└─────────────┘└┘└───────────────┘└─
doc  ───┘           └┘          └┘                └┘               └┘                 └─
txt  ───┘           └┘          └┘                └┘               └┘                 └─
par  ───┘           └┘          └┘                └┘               └┘                 └─
pid  ───┘           └┘          └┘                └┘               └┘                 └─
st   ───────────────────────────────────────────────────────────────────────────────────
1208      add_mul, mul_add, add_assoc, mul_assoc, _root_.zero_mul, _root_.mul_zero, sum_zero, sum_add],
id       └─────┘  └─────┘  └───────┘  └───────┘  └─────────────┘  └─────────────┘  └──────┘  └─────┘
src  ───┘└─────┘└┘└─────┘└┘└───────┘└┘└───────┘└┘└─────────────┘└┘└─────────────┘└┘└──────┘└┘└─────┘
typ  ───┘└─────┘└┘└─────┘└┘└───────┘└┘└───────┘└┘└─────────────┘└┘└─────────────┘└┘└──────┘└┘└─────┘
doc  ───┘       └┘       └┘         └┘         └┘               └┘               └┘        └┘       
txt  ───┘       └┘       └┘         └┘         └┘               └┘               └┘        └┘       
par  ───┘       └┘       └┘         └┘         └┘               └┘               └┘        └┘       
pid  ───┘       └┘       └┘         └┘         └┘               └┘               └┘        └┘       
st   ───────────────────────────────────────────────────────────────────────────────────────────────┘
1209    left_distrib  := left_distrib,
id                      └──────────┘
src                     └──────────┘
typ                     └──────────┘
1210    right_distrib := right_distrib,
id                      └───────────┘
src                     └───────────┘
typ                     └───────────┘
1211    .. finsupp.add_comm_monoid }
id        └─────────────────────┘
src       └─────────────────────┘
typ       └─────────────────────┘
1212  
1213  end
1214  
1215  instance [add_comm_monoid α] [comm_semiring β] : comm_semiring (α →₀ β) :=
id             └─────────────┘    └───────────┘     └───────────┘   └┘ 
src            └─────────────┘     └───────────┘      └───────────┘    └┘
typ            └─────────────┘    └───────────┘     └───────────┘   └┘ 
doc                                                                    └┘
1216  { mul_comm := assume f g,
id                         
typ                        
1217    begin
st     └─────
1218      simp only [mul_def, finsupp.sum, mul_comm],
id                  └─────┘  └─────────┘  └──────┘
src      └─────────┘└─────┘└┘└─────────┘└┘└──────┘
typ      └─────────┘└─────┘└┘└─────────┘└┘└──────┘
doc      └─────────┘       └┘└─────────┘└┘        
txt      └─────────┘       └┘           └┘        
par      └─────────┘       └┘           └┘        
pid          └──┘└┘       └┘           └┘        
st   ─────────────────────────────────────────────┘└─
1219      rw [finset.sum_comm],
id           └─────────────┘
src      └──┘└─────────────┘
typ      └──┘└─────────────┘
doc      └──┘               
txt      └──┘               
par      └──┘               
pid        └┘               
st   ──────────────────────┘└──
1220      simp only [add_comm]
id                  └──────┘
src      └─────────┘└──────┘└─
typ      └─────────┘└──────┘└─
doc      └─────────┘        └─
txt      └─────────┘        └─
par      └─────────┘        └─
pid          └──┘└┘        
st   ─────────────────────────
1221    end,
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘└─┘
1222    .. finsupp.semiring }
id        └──────────────┘
src       └──────────────┘
typ       └──────────────┘
1223  
1224  instance [add_monoid α] [ring β] : ring (α →₀ β) :=
id             └────────┘    └──┘     └──┘   └┘ 
src            └────────┘     └──┘      └──┘    └┘
typ            └────────┘    └──┘     └──┘   └┘ 
doc                                             └┘
1225  { neg := has_neg.neg,
id            └─────────┘
src           └─────────┘
typ           └─────────┘
1226    add_left_neg := add_left_neg,
id                     └──────────┘
src                    └──────────┘
typ                    └──────────┘
1227    .. finsupp.semiring }
id        └──────────────┘
src       └──────────────┘
typ       └──────────────┘
1228  
1229  instance [add_comm_monoid α] [comm_ring β] : comm_ring (α →₀ β) :=
id             └─────────────┘    └───────┘     └───────┘   └┘ 
src            └─────────────┘     └───────┘      └───────┘    └┘
typ            └─────────────┘    └───────┘     └───────┘   └┘ 
doc                                                            └┘
1230  { mul_comm := mul_comm, .. finsupp.ring}
id                 └──────┘     └──────────┘
src                └──────┘     └──────────┘
typ                └──────┘     └──────────┘
1231  
1232  lemma single_mul_single [has_add α] [semiring β] {a₁ a₂ : α} {b₁ b₂ : β}:
id                            └─────┘    └──────┘                       
src                           └─────┘     └──────┘
typ                           └─────┘    └──────┘                       
1233    single a₁ b₁ * single a₂ b₂ = single (a₁ + a₂) (b₁ * b₂) :=
id     └────┘ └┘ └┘  └────┘ └┘ └┘  └────┘  └┘  └┘   └┘  └┘
src    └────┘        └────┘        └────┘              
typ    └────┘ └┘ └┘  └────┘ └┘ └┘  └────┘  └┘  └┘   └┘  └┘
doc    └────┘         └────┘         └────┘
1234  (sum_single_index (by simp only [_root_.zero_mul, single_zero, sum_zero])).trans
id    └──────────────┘                └─────────────┘  └─────────┘  └──────┘   └───┘
src   └──────────────┘     └─────────┘└─────────────┘└┘└─────────┘└┘└──────┘  └───┘
typ   └──────────────┘     └─────────┘└─────────────┘└┘└─────────┘└┘└──────┘  └───┘
doc                        └─────────┘               └┘           └┘        
txt                        └─────────┘               └┘           └┘        
par                        └─────────┘               └┘           └┘        
pid                            └──┘└┘               └┘           └┘        
st                        └─────────────────────────────────────────────────┘
1235    (sum_single_index (by rw [_root_.mul_zero, single_zero]))
id      └──────────────┘         └─────────────┘  └─────────┘
src     └──────────────┘     └──┘└─────────────┘└┘└─────────┘
typ     └──────────────┘     └──┘└─────────────┘└┘└─────────┘
doc                          └──┘               └┘           
txt                          └──┘               └┘           
par                          └──┘               └┘           
pid                            └┘               └┘           
st                          └──────────────────┘└───────────┘
1236  
1237  lemma prod_single [add_comm_monoid α] [comm_semiring β]
id                      └─────────────┘    └───────────┘ 
src                     └─────────────┘     └───────────┘
typ                     └─────────────┘    └───────────┘ 
1238    {s : finset ι} {a : ι → α} {b : ι → β} :
id          └────┘                     
src         └────┘
typ         └────┘                     
doc         └────┘
1239    s.prod (λi, single (a i) (b i)) = single (s.sum a) (s.prod b) :=
id     └───┘     └────┘           └────┘  └──┘    └───┘ 
src     └───┘      └────┘               └────┘   └──┘      └───┘
typ    └───┘     └────┘           └────┘  └──┘    └───┘ 
doc     └───┘      └────┘                └────┘             └───┘
1240  finset.induction_on s rfl $ λ a s has ih, by rw [prod_insert has, ih,
id   └─────────────────┘  └─┘       └─┘ └┘         └─────────┘ └─┘  └┘
src  └─────────────────┘   └─┘                    └──┘└─────────┘   └┘  └─
typ  └─────────────────┘  └─┘       └─┘ └┘     └──┘└─────────┘└─┘└┘└┘└─
doc  └─────────────────┘                          └──┘              └┘  └─
txt                                               └──┘              └┘  └─
par                                               └──┘              └┘  └─
pid                                                 └┘              └┘  └─
st                                               └──────────────────┘└──┘└─
1241    single_mul_single, sum_insert has, prod_insert has]
id     └───────────────┘  └────────┘ └─┘  └─────────┘ └─┘
src  ─┘└───────────────┘└┘└────────┘   └┘└─────────┘   └─
typ  ─┘└───────────────┘└┘└────────┘└─┘└┘└─────────┘└─┘└─
doc  ─┘                 └┘             └┘              └─
txt  ─┘                 └┘             └┘              └─
par  ─┘                 └┘             └┘              └─
pid  ─┘                 └┘             └┘              
st   ──────────────────┘└──────────────┘└───────────────┘
1242  
src  
typ  
doc  
txt  
par  
pid  
st   
1243  section
1244  
1245  instance [semiring γ] [add_comm_monoid β] [semimodule γ β] : has_scalar γ (α →₀ β) := ⟨λa v, v.map_range ((•) a) (smul_zero _)⟩
id             └──────┘    └─────────────┘    └────────┘      └────────┘    └┘           └────────┘        └───────┘
src            └──────┘     └─────────────┘     └────────┘        └────────┘      └┘               └────────┘         └───────┘
typ            └──────┘    └─────────────┘    └────────┘      └────────┘    └┘           └────────┘        └───────┘
doc                                             └────────┘        └────────┘      └┘               └────────┘
1246  
1247  variables (α β)
1248  
1249  @[simp] lemma smul_apply' {R:semiring γ} [add_comm_monoid β] [semimodule γ β] {a : α} {b : γ} {v : α →₀ β} :
id                                └──────┘    └─────────────┘    └────────┘                        └┘ 
src                               └──────┘     └─────────────┘     └────────┘                             └┘
typ                               └──────┘    └─────────────┘    └────────┘                        └┘ 
doc    └──┘                                                        └────────┘                             └┘
1250    (b • v) a = b • (v a) := rfl
id                     └─┘
src                          └─┘
typ                    └─┘
1251  
1252  instance [semiring γ] [add_comm_monoid β] [semimodule γ β] : semimodule γ (α →₀ β) :=
id             └──────┘    └─────────────┘    └────────┘      └────────┘    └┘ 
src            └──────┘     └─────────────┘     └────────┘        └────────┘      └┘
typ            └──────┘    └─────────────┘    └────────┘      └────────┘    └┘ 
doc                                             └────────┘        └────────┘      └┘
1253  { smul      := (•),
id                  
src                 
typ                 
1254    smul_add  := λ a x y, finsupp.ext $ λ _, smul_add _ _ _,
id                        └─────────┘       └──────┘
src                          └─────────┘        └──────┘
typ                       └─────────┘       └──────┘
1255    add_smul  := λ a x y, finsupp.ext $ λ _, add_smul _ _ _,
id                        └─────────┘       └──────┘
src                          └─────────┘        └──────┘
typ                       └─────────┘       └──────┘
1256    one_smul  := λ x, finsupp.ext $ λ _, one_smul _ _,
id                      └─────────┘       └──────┘
src                      └─────────┘        └──────┘
typ                     └─────────┘       └──────┘
1257    mul_smul  := λ r s x, finsupp.ext $ λ _, mul_smul _ _ _,
id                        └─────────┘       └──────┘
src                          └─────────┘        └──────┘
typ                       └─────────┘       └──────┘
1258    zero_smul := λ x, finsupp.ext $ λ _, zero_smul _ _,
id                      └─────────┘       └───────┘
src                      └─────────┘        └───────┘
typ                     └─────────┘       └───────┘
1259    smul_zero := λ x, finsupp.ext $ λ _, smul_zero _ }
id                      └─────────┘       └───────┘
src                      └─────────┘        └───────┘
typ                     └─────────┘       └───────┘
1260  
1261  instance [ring γ] [add_comm_group β] [module γ β] : module γ (α →₀ β) :=
id             └──┘    └────────────┘    └────┘      └────┘    └┘ 
src            └──┘     └────────────┘     └────┘        └────┘      └┘
typ            └──┘    └────────────┘    └────┘      └────┘    └┘ 
doc                                        └────┘        └────┘      └┘
1262  { ..finsupp.semimodule α β }
id       └────────────────┘  
src      └────────────────┘
typ      └────────────────┘  
1263  
1264  instance [discrete_field γ] [add_comm_group β] [vector_space γ β] : vector_space γ (α →₀ β) :=
id             └────────────┘    └────────────┘    └──────────┘      └──────────┘    └┘ 
src            └────────────┘     └────────────┘     └──────────┘        └──────────┘      └┘
typ            └────────────┘    └────────────┘    └──────────┘      └──────────┘    └┘ 
doc                                                  └──────────┘        └──────────┘      └┘
1265  { ..finsupp.module α β }
id       └────────────┘  
src      └────────────┘
typ      └────────────┘  
1266  
1267  variables {α β}
1268  lemma support_smul {R:semiring γ} [add_comm_monoid β] [semimodule γ β] {b : γ} {g : α →₀ β} :
id                         └──────┘    └─────────────┘    └────────┘                 └┘ 
src                        └──────┘     └─────────────┘     └────────┘                     └┘
typ                        └──────┘    └─────────────┘    └────────┘                 └┘ 
doc                                                         └────────┘                     └┘
1269    (b • g).support ⊆ g.support :=
id         └─────┘   └──────┘
src          └─────┘    └──────┘
typ        └─────┘   └──────┘
1270  λ a, by simp; exact mt (λ h, h.symm ▸ smul_zero _)
id                      └┘        └───┘  └───────┘
src          └──┘  └────┘└┘  └──┘ └───┘└───────┘└───
typ         └──┘  └────┘└┘  └──┘ └───┘└───────┘└───
doc          └──┘  └────┘    └──┘                └───
txt          └──┘  └────┘    └──┘                └───
par          └──┘  └────┘    └──┘                └───
pid                         └──┘                └─┘
st          └───────────────────────────────────────────
1271  
src  
typ  
doc  
txt  
par  
pid  
st   
1272  section
1273  variables {α' : Type*} [has_zero δ] {p : α → Prop}
id                           └──────┘
src                          └──────┘
typ                          └──────┘
1274  
1275  @[simp] lemma filter_smul {R : semiring γ} [add_comm_monoid β] [semimodule γ β]
id                                  └──────┘    └─────────────┘    └────────┘  
src                                 └──────┘     └─────────────┘     └────────┘
typ                                 └──────┘    └─────────────┘    └────────┘  
doc    └──┘                                                          └────────┘
1276    {b : γ} {v : α →₀ β} : (b • v).filter p = b • v.filter p :=
id                  └┘         └────┘      └─────┘ 
src                   └┘            └────┘         └─────┘
typ                 └┘         └────┘      └─────┘ 
doc                   └┘             └────┘           └─────┘
1277  ext $ λ a, by by_cases p a; simp [h]
id   └─┘                            
src  └─┘           └───────┘    └────┘ └┘
typ  └─┘          └───────┘  └────┘└┘
doc                └───────┘    └────┘ └┘
txt                └───────┘    └────┘ └┘
par                └───────┘    └────┘ └┘
pid                                 
st                └──────────────────────┘
1278  end
1279  
1280  lemma map_domain_smul {α'} {R : semiring γ} [add_comm_monoid β] [semimodule γ β]
id                                   └──────┘    └─────────────┘    └────────┘  
src                                  └──────┘     └─────────────┘     └────────┘
typ                                  └──────┘    └─────────────┘    └────────┘  
doc                                                                   └────────┘
1281     {f : α → α'} (b : γ) (v : α →₀ β) : map_domain f (b • v) = b • map_domain f v :=
id              └┘               └┘     └────────┘          └────────┘  
src                                 └┘      └────────┘              └────────┘
typ             └┘               └┘     └────────┘          └────────┘  
doc                                 └┘      └────────┘                 └────────┘
1282  begin
st   └─────
1283    change map_domain f (map_range _ _ _) = map_range _ _ _,
id            └────────┘                     └───────┘
src    └─────┘└────────┘           └──────┘└───────┘└────┘
typ    └─────┘└────────┘          └──────┘└───────┘└────┘
doc    └─────┘└────────┘           └──────┘ └───────┘└────┘
txt    └─────┘                     └──────┘          └────┘
par    └─────┘                     └──────┘          └────┘
pid                               └──────┘          └────┘
st   ────────────────────────────────────────────────────────┘└─
1284    apply finsupp.induction v, {simp},
id           └───────────────┘ 
src    └────┘└───────────────┘    └──┘
typ    └────┘└───────────────┘   └──┘
doc    └────┘                     └──┘
txt    └────┘                     └──┘
par    └────┘                     └──┘
pid                          
st   ──────────────────────────┘└─────┘└┘
1285    intros a b v' hv₁ hv₂ IH,
src    └──────────────────────┘
typ    └──────────────────────┘
doc    └──────────────────────┘
txt    └──────────────────────┘
par    └──────────────────────┘
pid          └────────────────┘
st   ─────────────────────────┘└─
1286    rw [map_range_add, map_domain_add, IH, map_domain_add, map_range_add,
id         └───────────┘  └────────────┘  └┘  └────────────┘  └───────────┘
src    └──┘└───────────┘└┘└────────────┘└┘  └┘└────────────┘└┘└───────────┘└─
typ    └──┘└───────────┘└┘└────────────┘└┘└┘└┘└────────────┘└┘└───────────┘└─
doc    └──┘             └┘              └┘  └┘              └┘             └─
txt    └──┘             └┘              └┘  └┘              └┘             └─
par    └──┘             └┘              └┘  └┘              └┘             └─
pid      └┘             └┘              └┘  └┘              └┘             └─
st   ──────────────────┘└──────────────┘└──┘└──────────────┘└─────────────┘└─
1287      map_range_single, map_domain_single, map_domain_single, map_range_single];
id       └──────────────┘  └───────────────┘  └───────────────┘  └──────────────┘
src  ───┘└──────────────┘└┘└───────────────┘└┘└───────────────┘└┘└──────────────┘
typ  ───┘└──────────────┘└┘└───────────────┘└┘└───────────────┘└┘└──────────────┘
doc  ───┘                └┘                 └┘                 └┘                
txt  ───┘                └┘                 └┘                 └┘                
par  ───┘                └┘                 └┘                 └┘                
pid  ───┘                └┘                 └┘                 └┘                
st   ───────────────────┘└─────────────────┘└─────────────────┘└────────────────┘└─
1288    apply smul_add
id           └──────┘
src    └────┘└──────┘
typ    └────┘└──────┘
doc    └────┘        
txt    └────┘        
par    └────┘        
pid                 
st   ────────────────┘
1289  end
st   └─┘
1290  
1291  @[simp] lemma smul_single {R : semiring γ} [add_comm_monoid β] [semimodule γ β]
id                                  └──────┘    └─────────────┘    └────────┘  
src                                 └──────┘     └─────────────┘     └────────┘
typ                                 └──────┘    └─────────────┘    └────────┘  
doc    └──┘                                                          └────────┘
1292    (c : γ) (a : α) (b : β) : c • finsupp.single a b = finsupp.single a (c • b) :=
id                              └────────────┘    └────────────┘     
src                                 └────────────┘      └────────────┘      
typ                             └────────────┘    └────────────┘     
doc                                  └────────────┘       └────────────┘
1293  ext $ λ a', by by_cases a = a'; [{subst h, simp}, simp [h]]
id   └─┘     └┘                └┘                        
src  └─┘            └───────┘      └────┘   └──┘   └────┘ 
typ  └─┘     └┘     └───────┘└┘   └────┘  └──┘   └────┘
doc                 └───────┘        └────┘   └──┘   └────┘ 
txt                 └───────┘        └────┘   └──┘   └────┘ 
par                 └───────┘        └────┘   └──┘   └────┘ 
pid                                                     
st                 └─────────────────┘└──────┘└────┘└┘└────────┘
1294  
1295  end
1296  
1297  @[simp] lemma smul_apply [ring β] {a : α} {b : β} {v : α →₀ β} :
id                             └──┘                       └┘ 
src                            └──┘                           └┘
typ                            └──┘                       └┘ 
doc    └──┘                                                   └┘
1298    (b • v) a = b • (v a) := rfl
id                     └─┘
src                          └─┘
typ                    └─┘
1299  
1300  lemma sum_smul_index [ring β] [add_comm_monoid γ] {g : α →₀ β} {b : β} {h : α → β → γ}
id                         └──┘    └─────────────┘         └┘                     
src                        └──┘     └─────────────┘           └┘
typ                        └──┘    └─────────────┘         └┘                     
doc                                                           └┘
1301    (h0 : ∀i, h i 0 = 0) : (b • g).sum h = g.sum (λi a, h i (b * a)) :=
id                            └─┘    └──┘           
src                                └─┘      └──┘               
typ                           └─┘    └──┘           
doc                                  └─┘       └──┘
1302  finsupp.sum_map_range_index h0
id   └─────────────────────────┘ └┘
src  └─────────────────────────┘
typ  └─────────────────────────┘ └┘
1303  
1304  section
1305  variables [semiring β] [semiring γ]
id              └──────┘     └──────┘
src             └──────┘     └──────┘
typ             └──────┘     └──────┘
1306  
1307  lemma sum_mul (b : γ) (s : α →₀ β) {f : α → β → γ} :
id                              └┘              
src                               └┘
typ                             └┘              
doc                               └┘
1308    (s.sum f) * b = s.sum (λ a c, (f a (s a)) * b) :=
id      └──┘      └──┘                
src      └──┘         └──┘                     
typ     └──┘      └──┘                
doc      └──┘           └──┘
1309  by simp only [finsupp.sum, finset.sum_mul]
id                 └─────────┘  └────────────┘
src     └─────────┘└─────────┘└┘└────────────┘└─
typ     └─────────┘└─────────┘└┘└────────────┘└─
doc     └─────────┘└─────────┘└┘              └─
txt     └─────────┘           └┘              └─
par     └─────────┘           └┘              └─
pid         └──┘└┘           └┘              
st     └────────────────────────────────────────
1310  
src  
typ  
doc  
txt  
par  
pid  
st   
1311  lemma mul_sum (b : γ) (s : α →₀ β) {f : α → β → γ} :
id                              └┘              
src                               └┘
typ                             └┘              
doc                               └┘
1312    b * (s.sum f) = s.sum (λ a c, b * (f a (s a))) :=
id        └──┘    └──┘              
src         └──┘      └──┘           
typ       └──┘    └──┘              
doc          └──┘       └──┘
1313  by simp only [finsupp.sum, finset.mul_sum]
id                 └─────────┘  └────────────┘
src     └─────────┘└─────────┘└┘└────────────┘└─
typ     └─────────┘└─────────┘└┘└────────────┘└─
doc     └─────────┘└─────────┘└┘              └─
txt     └─────────┘           └┘              └─
par     └─────────┘           └┘              └─
pid         └──┘└┘           └┘              
st     └────────────────────────────────────────
1314  
src  
typ  
doc  
txt  
par  
pid  
st   
1315  protected lemma eq_zero_of_zero_eq_one
1316    (zero_eq_one : (0 : β) = 1) (l : α →₀ β) : l = 0 :=
id                                     └┘      
src                                      └┘        
typ                                    └┘      
doc                                       └┘
1317    by ext i; simp [eq_zero_of_zero_eq_one β zero_eq_one (l i)]
id                     └────────────────────┘  └─────────┘   
src       └───┘  └────┘└────────────────────┘               └──
typ       └───┘  └────┘└────────────────────┘└─────────┘ └──
doc       └───┘  └────┘└────────────────────┘               └──
txt       └───┘  └────┘                                     └──
par       └───┘  └────┘                                     └──
pid          └┘                                           └┘
st       └─────────────────────────────────────────────────────────
1318  
src  
typ  
doc  
txt  
par  
pid  
st   
1319  end
1320  
1321  def restrict_support_equiv [add_comm_monoid β] (s : set α) :
id                               └─────────────┘        └─┘ 
src                              └─────────────┘         └─┘
typ                              └─────────────┘        └─┘ 
1322    {f : α →₀ β // ↑f.support ⊆ s } ≃ (s →₀ β):=
id          └┘     └──────┘        └┘ 
src          └┘       └──────┘          └┘
typ         └┘     └──────┘        └┘ 
doc           └┘                           └┘
1323  begin
st   └─────
1324    refine ⟨λf, subtype_domain (λx, x ∈ s) f.1, λ f, ⟨f.map_domain subtype.val, _⟩, _, _⟩,
id                 └────────────┘                       └─────────┘ └─────────┘
src    └─────┘  └─┘└────────────┘  └─┘  └┘ └──┘ └──┘  └─────────┘└─────────┘└─────────┘
typ    └─────┘  └─┘└────────────┘  └─┘ └┘ └──┘ └──┘  └─────────┘└─────────┘└─────────┘
doc    └─────┘  └─┘└────────────┘  └─┘   └┘ └──┘ └──┘  └─────────┘           └─────────┘
txt    └─────┘  └─┘                └─┘   └┘ └──┘ └──┘                        └─────────┘
par    └─────┘  └─┘                └─┘   └┘ └──┘ └──┘                        └─────────┘
pid            └─┘                └─┘   └┘ └──┘ └──┘                        └─────────┘
st   ──────────────────────────────────────────────────────────────────────────────────────┘└─
1325    { refine set.subset.trans (finset.coe_subset.2 map_domain_support) _,
id              └──────────────┘  └───────────────┘   └────────────────┘
src      └─────┘└──────────────┘ └───────────────┘└─┘└────────────────┘└─┘
typ      └─────┘└──────────────┘ └───────────────┘└─┘└────────────────┘└─┘
doc      └─────┘                                  └─┘                  └─┘
txt      └─────┘                                  └─┘                  └─┘
par      └─────┘                                  └─┘                  └─┘
pid                                              └─┘                  └─┘
st   ───┘└────────────────────────────────────────────────────────────────┘└─
1326      rw [finset.coe_image, set.image_subset_iff],
id           └──────────────┘  └──────────────────┘
src      └──┘└──────────────┘└┘└──────────────────┘
typ      └──┘└──────────────┘└┘└──────────────────┘
doc      └──┘                └┘└──────────────────┘
txt      └──┘                └┘                    
par      └──┘                └┘                    
pid        └┘                └┘                    
st   ───────────────────────┘└────────────────────┘└──
1327      exact assume x hx, x.2 },
src      └────┘      └─────┘ └─┘
typ      └────┘      └─────┘ └─┘
doc      └────┘      └─────┘ └─┘
txt      └────┘      └─────┘ └─┘
par      └────┘      └─────┘ └─┘
pid                 └─────┘ └─┘
st   ──────────────────────────┘└┘
1328    { rintros ⟨f, hf⟩,
src      └─────────────┘
typ      └─────────────┘
doc      └─────────────┘
txt      └─────────────┘
par      └─────────────┘
pid             └──────┘
st   ───┘└─────────────┘└─
1329      apply subtype.eq,
id             └────────┘
src      └────┘└────────┘
typ      └────┘└────────┘
doc      └────┘
txt      └────┘
par      └────┘
pid           
st   ───────────────────┘└─
1330      ext a,
src      └───┘
typ      └───┘
doc      └───┘
txt      └───┘
par      └───┘
pid         └┘
st   ────────┘└─
1331      dsimp only,
src      └────────┘
typ      └────────┘
doc      └────────┘
txt      └────────┘
par      └────────┘
pid           └───┘
st   ─────────────┘└─
1332      refine classical.by_cases (assume h : a ∈ set.range (subtype.val : s → α), _) (assume h, _),
id              └────────────────┘               └───────┘  └─────────┘      
src      └─────┘└────────────────┘       └───┘  └───────┘ └─────────┘└─┘   └────┘       └────┘
typ      └─────┘└────────────────┘       └───┘└───────┘ └─────────┘└─┘ └────┘       └────┘
doc      └─────┘                         └───┘  └───────┘            └─┘   └────┘       └────┘
txt      └─────┘                         └───┘                       └─┘   └────┘       └────┘
par      └─────┘                         └───┘                       └─┘   └────┘       └────┘
pid                                     └───┘                       └─┘   └────┘       └────┘
st   ──────────────────────────────────────────────────────────────────────────────────────────────┘└─
1333      { rcases h with ⟨x, rfl⟩,
id                
src        └─────┘ └────────────┘
typ        └─────┘└────────────┘
doc        └─────┘ └────────────┘
txt        └─────┘ └────────────┘
par        └─────┘ └────────────┘
pid               └────────────┘
st   ─────┘└────────────────────┘└─
1334        rw [map_domain_apply subtype.val_injective, subtype_domain_apply] },
id             └──────────────┘ └───────────────────┘  └──────────────────┘
src        └──┘└──────────────┘└───────────────────┘└┘└──────────────────┘└┘
typ        └──┘└──────────────┘└───────────────────┘└┘└──────────────────┘└┘
doc        └──┘                                     └┘                    └┘
txt        └──┘                                     └┘                    └┘
par        └──┘                                     └┘                    └┘
pid          └┘                                     └┘                    
st   ───────────────────────────────────────────────┘└────────────────────┘└┘
1335      { convert map_domain_notin_range _ _ h,
id                 └────────────────────┘     
src        └──────┘└────────────────────┘└───┘
typ        └──────┘└────────────────────┘└───┘
doc        └──────┘                      └───┘
txt        └──────┘                      └───┘
par        └──────┘                      └───┘
pid                                     └───┘
st   ─────────────────────────────────────────┘└─
1336        rw [← not_mem_support_iff],
id               └─────────────────┘
src        └────┘└─────────────────┘
typ        └────┘└─────────────────┘
doc        └────┘                   
txt        └────┘                   
par        └────┘                   
pid          └──┘                   
st   ──────────────────────────────┘└──
1337        refine mt _ h,
id                └┘   
src        └─────┘└┘└─┘
typ        └─────┘└┘└─┘
doc        └─────┘  └─┘
txt        └─────┘  └─┘
par        └─────┘  └─┘
pid                └─┘
st   ──────────────────┘└─
1338        exact assume ha, ⟨⟨a, hf ha⟩, rfl⟩ } },
id                              └┘      └─┘
src        └────┘      └───┘   └┘    └─┘└─┘└┘
typ        └────┘      └───┘  └┘└┘  └─┘└─┘└┘
doc        └────┘      └───┘   └┘    └─┘   └┘
txt        └────┘      └───┘   └┘    └─┘   └┘
par        └────┘      └───┘   └┘    └─┘   └┘
pid                   └───┘   └┘    └─┘   
st   ────────────────────────────────────────┘└──┘
1339    { assume f,
src      └──────┘
typ      └──────┘
doc      └──────┘
txt      └──────┘
par      └──────┘
pid      └──────┘
st   ───────────┘└─
1340      ext ⟨a, ha⟩,
src      └─────────┘
typ      └─────────┘
doc      └─────────┘
txt      └─────────┘
par      └─────────┘
pid         └──────┘
st   ──────────────┘└─
1341      dsimp only,
src      └────────┘
typ      └────────┘
doc      └────────┘
txt      └────────┘
par      └────────┘
pid           └───┘
st   ─────────────┘└─
1342      rw [subtype_domain_apply, map_domain_apply subtype.val_injective] }
id           └──────────────────┘  └──────────────┘ └───────────────────┘
src      └──┘└──────────────────┘└┘└──────────────┘└───────────────────┘└┘
typ      └──┘└──────────────────┘└┘└──────────────┘└───────────────────┘└┘
doc      └──┘                    └┘                                     └┘
txt      └──┘                    └┘                                     └┘
par      └──┘                    └┘                                     └┘
pid        └┘                    └┘                                     
st   ───────────────────────────┘└──────────────────────────────────────┘└─
1343  end
st   ──┘
1344  
1345  protected def dom_congr [add_comm_monoid β] (e : α₁ ≃ α₂) : (α₁ →₀ β) ≃ (α₂ →₀ β) :=
id                            └─────────────┘        └┘  └┘     └┘ └┘     └┘ └┘ 
src                           └─────────────┘                       └┘         └┘
typ                           └─────────────┘        └┘  └┘     └┘ └┘     └┘ └┘ 
doc                                                                 └┘         └┘
1346  ⟨map_domain e, map_domain e.symm,
id    └────────┘   └────────┘ └───┘
src   └────────┘    └────────┘  └───┘
typ   └────────┘   └────────┘ └───┘
doc   └────────┘    └────────┘
1347    begin
st     └─────
1348      assume v,
src      └──────┘
typ      └──────┘
doc      └──────┘
txt      └──────┘
par      └──────┘
pid      └──────┘
st   ───────────┘└─
1349      simp only [map_domain_comp.symm, (∘), equiv.symm_apply_apply],
id                                            └────────────────────┘
src      └─────────┘                    └┘└──┘└────────────────────┘
typ      └─────────┘└──────────────────┘└┘└──┘└────────────────────┘
doc      └─────────┘                    └┘ └──┘                      
txt      └─────────┘                    └┘ └──┘                      
par      └─────────┘                    └┘ └──┘                      
pid          └──┘└┘                    └┘ └──┘                      
st   ────────────────────────────────────────────────────────────────┘└─
1350      exact map_domain_id
id             └───────────┘
src      └────┘└───────────┘
typ      └────┘└───────────┘
doc      └────┘             
txt      └────┘             
par      └────┘             
pid                        
st   ────────────────────────
1351    end,
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘└─┘
1352    begin
st     └─────
1353      assume v,
src      └──────┘
typ      └──────┘
doc      └──────┘
txt      └──────┘
par      └──────┘
pid      └──────┘
st   ───────────┘└─
1354      simp only [map_domain_comp.symm, (∘), equiv.apply_symm_apply],
id                                            └────────────────────┘
src      └─────────┘                    └┘└──┘└────────────────────┘
typ      └─────────┘└──────────────────┘└┘└──┘└────────────────────┘
doc      └─────────┘                    └┘ └──┘                      
txt      └─────────┘                    └┘ └──┘                      
par      └─────────┘                    └┘ └──┘                      
pid          └──┘└┘                    └┘ └──┘                      
st   ────────────────────────────────────────────────────────────────┘└─
1355      exact map_domain_id
id             └───────────┘
src      └────┘└───────────┘
typ      └────┘└───────────┘
doc      └────┘             
txt      └────┘             
par      └────┘             
pid                        
st   ────────────────────────
1356    end⟩
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘└─┘
1357  
1358  section sigma
1359  
1360  variables {αs : ι → Type*} [has_zero β] (l : (Σ i, αs i) →₀ β)
id                               └──────┘                 └┘
src                              └──────┘                   └┘
typ                              └──────┘                 └┘
doc                                                           └┘
1361  
1362  noncomputable def split (i : ι) : αs i →₀ β :=
id                                    └┘  └┘ 
src                                         └┘
typ                                   └┘  └┘ 
doc                                         └┘
1363  l.comap_domain (sigma.mk i) (λ x1 x2 _ _ hx, heq_iff_eq.1 (sigma.mk.inj hx).2)
id   └───────────┘  └──────┘      └┘ └┘   └┘  └────────┘   └──────────┘ └┘ 
src   └───────────┘  └──────┘                     └────────┘   └──────────┘    
typ  └───────────┘  └──────┘      └┘ └┘   └┘  └────────┘   └──────────┘ └┘ 
1364  
1365  lemma split_apply (i : ι) (x : αs i) : split l i x = l ⟨i, x⟩ :=
id                                 └┘     └───┘         
src                                         └───┘       
typ                                └┘     └───┘         
1366  begin
st   └─────
1367   dunfold split,
src   └───────────┘
typ   └───────────┘
doc   └───────────┘
txt   └───────────┘
par   └───────────┘
pid          └────┘
st   ─────────────┘└─
1368   rw comap_domain_apply
id       └────────────────┘
src   └─┘└────────────────┘
typ   └─┘└────────────────┘
doc   └─┘                  
txt   └─┘                  
par   └─┘                  
pid                       
st   ──────────────────────┘
1369  end
st   └─┘
1370  
1371  def split_support : finset ι := l.support.image sigma.fst
id                       └────┘     └──────┘└────┘ └───────┘
src                      └────┘       └──────┘└────┘ └───────┘
typ                      └────┘     └──────┘└────┘ └───────┘
doc                      └────┘               └────┘
1372  
1373  lemma mem_split_support_iff_nonzero (i : ι) :
id                                            
typ                                           
1374    i ∈ split_support l ↔ split l i ≠ 0 :=
id       └───────────┘   └───┘   
src       └───────────┘    └───┘     
typ      └───────────┘   └───┘   
1375  begin
st   └─────
1376    classical,
src    └───────┘
typ    └───────┘
doc    └───────┘
txt    └───────┘
par    └───────┘
st   ──────────┘└─
1377    rw [split_support, mem_image, ne.def, ← support_eq_empty, ← ne.def,
id         └───────────┘  └───────┘  └────┘    └──────────────┘    └────┘
src    └──┘└───────────┘└┘└───────┘└┘└────┘└──┘└──────────────┘└──┘└────┘└─
typ    └──┘└───────────┘└┘└───────┘└┘└────┘└──┘└──────────────┘└──┘└────┘└─
doc    └──┘             └┘         └┘      └──┘                └──┘      └─
txt    └──┘             └┘         └┘      └──┘                └──┘      └─
par    └──┘             └┘         └┘      └──┘                └──┘      └─
pid      └┘             └┘         └┘      └──┘                └──┘      └─
st   ──────────────────┘└─────────┘└──────┘└──────────────────┘└────────┘└─
1378      ← finset.nonempty_iff_ne_empty, split, comap_domain, finset.nonempty],
id         └──────────────────────────┘  └───┘  └──────────┘  └─────────────┘
src  ─────┘└──────────────────────────┘└┘└───┘└┘└──────────┘└┘└─────────────┘
typ  ─────┘└──────────────────────────┘└┘└───┘└┘└──────────┘└┘└─────────────┘
doc  ─────┘                            └┘     └┘            └┘└─────────────┘
txt  ─────┘                            └┘     └┘            └┘               
par  ─────┘                            └┘     └┘            └┘               
pid  ─────┘                            └┘     └┘            └┘               
st   ─────────────────────────────────┘└─────┘└────────────┘└───────────────┘└──
1379    simp
src    └───┘
typ    └───┘
doc    └───┘
txt    └───┘
par    └───┘
pid        
st   ──────┘
1380  end
st   └─┘
1381  
1382  noncomputable def split_comp [has_zero γ] (g : Π i, (αs i →₀ β) → γ)
id                                 └──────┘             └┘  └┘     
src                                └──────┘                    └┘
typ                                └──────┘             └┘  └┘     
doc                                                            └┘
1383    (hg : ∀ i x, x = 0 ↔ g i x = 0) : ι →₀ γ :=
id                               └┘ 
src                                     └┘
typ                              └┘ 
doc                                        └┘
1384  { support := split_support l,
id                └───────────┘ 
src               └───────────┘
typ               └───────────┘ 
1385    to_fun := λ i, g i (split l i),
id                      └───┘  
src                        └───┘
typ                     └───┘  
1386    mem_support_to_fun :=
1387    begin
st     └─────
1388      intros i,
src      └──────┘
typ      └──────┘
doc      └──────┘
txt      └──────┘
par      └──────┘
pid            └┘
st   ───────────┘└─
1389      rw mem_split_support_iff_nonzero,
id          └───────────────────────────┘
src      └─┘└───────────────────────────┘
typ      └─┘└───────────────────────────┘
doc      └─┘
txt      └─┘
par      └─┘
pid        
st   ───────────────────────────────────┘└─
1390      haveI := classical.dec,
id                └───────────┘
src      └───────┘└───────────┘
typ      └───────┘└───────────┘
doc      └───────┘
txt      └───────┘
par      └───────┘
pid           └─┘
st   ─────────────────────────┘└─
1391      rwa not_iff_not,
id           └─────────┘
src      └──┘└─────────┘
typ      └──┘└─────────┘
doc      └──┘
txt      └──┘
par      └──┘
pid         
st   ──────────────────┘└─
1392      exact hg _ _,
id             └┘
src      └────┘  └──┘
typ      └────┘└┘└──┘
doc      └────┘  └──┘
txt      └────┘  └──┘
par      └────┘  └──┘
pid             └──┘
st   ───────────────┘└─
1393    end }
st   ────┘
1394  
1395  lemma sigma_support : l.support = l.split_support.sigma (λ i, (l.split i).support) :=
id                         └──────┘  └────────────┘└────┘       └────┘  └─────┘
src                         └──────┘   └────────────┘└────┘         └────┘   └─────┘
typ                        └──────┘  └────────────┘└────┘       └────┘  └─────┘
doc                                                   └────┘
1396  by simp [finset.ext, split_support, split, comap_domain]; tauto
id            └────────┘  └───────────┘  └───┘  └──────────┘
src     └────┘└────────┘└┘└───────────┘└┘└───┘└┘└──────────┘  └─────
typ     └────┘└────────┘└┘└───────────┘└┘└───┘└┘└──────────┘  └─────
doc     └────┘          └┘             └┘     └┘              └─────
txt     └────┘          └┘             └┘     └┘              └─────
par     └────┘          └┘             └┘     └┘              └─────
pid                   └┘             └┘     └┘                   
st     └─────────────────────────────────────────────────────────────
1397  
src  
typ  
doc  
txt  
par  
pid  
st   
1398  lemma sigma_sum [add_comm_monoid γ] (f : (Σ (i : ι), αs i) → β → γ) :
id                    └─────────────┘                 └┘        
src                   └─────────────┘                  
typ                   └─────────────┘                 └┘        
1399    l.sum f = (split_support l).sum (λ (i : ι), (split l i).sum (λ (a : αs i) b, f ⟨i, a⟩ b)) :=
id     └──┘    └───────────┘  └─┘              └───┘   └─┘          └┘           
src     └──┘     └───────────┘   └─┘               └───┘     └─┘
typ    └──┘    └───────────┘  └─┘              └───┘   └─┘          └┘           
doc     └──┘                                                  └─┘
1400  by simp [sum, sigma_support, sum_sigma,split_apply]
id            └─┘  └───────────┘  └───────┘ └─────────┘
src     └────┘└─┘└┘└───────────┘└┘└───────┘└─────────┘└─
typ     └────┘└─┘└┘└───────────┘└┘└───────┘└─────────┘└─
doc     └────┘└─┘└┘             └┘                    └─
txt     └────┘   └┘             └┘                    └─
par     └────┘   └┘             └┘                    └─
pid            └┘             └┘                    
st     └─────────────────────────────────────────────────
1401  
src  
typ  
doc  
txt  
par  
pid  
st   
1402  end sigma
1403  
1404  end finsupp
1405  
1406  namespace multiset
1407  
1408  def to_finsupp (s : multiset α) : α →₀ ℕ :=
id                       └──────┘      └┘ 
src                      └──────┘        └┘ 
typ                      └──────┘      └┘ 
doc                      └──────┘        └┘
1409  { support := s.to_finset,
id                └────────┘
src                └────────┘
typ               └────────┘
doc                └────────┘
1410    to_fun := λ a, s.count a,
id                   └────┘ 
src                    └────┘
typ                  └────┘ 
doc                    └────┘
1411    mem_support_to_fun := λ a,
id                             
typ                            
1412    begin
st     └─────
1413      rw mem_to_finset,
id          └───────────┘
src      └─┘└───────────┘
typ      └─┘└───────────┘
doc      └─┘
txt      └─┘
par      └─┘
pid        
st   ───────────────────┘└─
1414      convert not_iff_not_of_iff (count_eq_zero.symm),
id               └────────────────┘  └────────────────┘
src      └──────┘└────────────────┘ └────────────────┘
typ      └──────┘└────────────────┘ └────────────────┘
doc      └──────┘                                     
txt      └──────┘                                     
par      └──────┘                                     
pid                                                  
st   ──────────────────────────────────────────────────┘└─
1415      rw not_not
id          └─────┘
src      └─┘└─────┘
typ      └─┘└─────┘
doc      └─┘       
txt      └─┘       
par      └─┘       
pid               
st   ───────────────
1416    end }
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘└─┘
1417  
1418  @[simp] lemma to_finsupp_support (s : multiset α) :
id                                         └──────┘ 
src                                        └──────┘
typ                                        └──────┘ 
doc    └──┘                                └──────┘
1419    s.to_finsupp.support = s.to_finset := rfl
id     └─────────┘└──────┘  └────────┘    └─┘
src     └─────────┘└──────┘   └────────┘    └─┘
typ    └─────────┘└──────┘  └────────┘    └─┘
doc                            └────────┘
1420  
1421  @[simp] lemma to_finsupp_apply (s : multiset α) (a : α) :
id                                       └──────┘        
src                                      └──────┘
typ                                      └──────┘        
doc    └──┘                              └──────┘
1422    s.to_finsupp a = s.count a := rfl
id     └─────────┘   └────┘     └─┘
src     └─────────┘     └────┘      └─┘
typ    └─────────┘   └────┘     └─┘
doc                      └────┘
1423  
1424  @[simp] lemma to_finsupp_zero :
doc    └──┘
1425    to_finsupp (0 : multiset α) = 0 :=
id     └────────┘      └──────┘   
src    └────────┘      └──────┘    
typ    └────────┘      └──────┘   
doc                    └──────┘
1426  finsupp.ext $ λ a, count_zero a
id   └─────────┘       └────────┘ 
src  └─────────┘        └────────┘
typ  └─────────┘       └────────┘ 
1427  
1428  @[simp] lemma to_finsupp_add (s t : multiset α) :
id                                       └──────┘ 
src                                      └──────┘
typ                                      └──────┘ 
doc    └──┘                              └──────┘
1429    to_finsupp (s + t) = to_finsupp s + to_finsupp t :=
id     └────────┘       └────────┘   └────────┘ 
src    └────────┘         └────────┘    └────────┘
typ    └────────┘       └────────┘   └────────┘ 
1430  finsupp.ext $ λ a, count_add a s t
id   └─────────┘       └───────┘   
src  └─────────┘        └───────┘
typ  └─────────┘       └───────┘   
1431  
1432  lemma to_finsupp_singleton (a : α) :
id                                   
typ                                  
1433    to_finsupp {a} = finsupp.single a 1 :=
id     └────────┘    └────────────┘ 
src    └────────┘     └────────────┘
typ    └────────┘    └────────────┘ 
doc                     └────────────┘
1434  finsupp.ext $ λ b,
id   └─────────┘     
src  └─────────┘
typ  └─────────┘     
1435  if h : a = b then by simp [finsupp.single_apply, h] else
id   └┘                      └──────────────────┘  
src  └┘                  └────┘└──────────────────┘└┘ └┘
typ  └┘                └────┘└──────────────────┘└┘└┘
doc                       └────┘                    └┘ └┘
txt                       └────┘                    └┘ └┘
par                       └────┘                    └┘ └┘
pid                                               └┘ 
st                       └──────────────────────────────┘
1436  begin
st   └─────
1437    rw [to_finsupp_apply, finsupp.single_apply, if_neg h, count_eq_zero,
id         └──────────────┘  └──────────────────┘  └────┘   └───────────┘
src    └──┘└──────────────┘└┘└──────────────────┘└┘└────┘ └┘└───────────┘└─
typ    └──┘└──────────────┘└┘└──────────────────┘└┘└────┘└┘└───────────┘└─
doc    └──┘                └┘                    └┘       └┘             └─
txt    └──┘                └┘                    └┘       └┘             └─
par    └──┘                └┘                    └┘       └┘             └─
pid      └┘                └┘                    └┘       └┘             └─
st   ─────────────────────┘└────────────────────┘└────────┘└─────────────┘└─
1438        singleton_eq_singleton, mem_singleton],
id         └────────────────────┘  └───────────┘
src  ─────┘└────────────────────┘└┘└───────────┘
typ  ─────┘└────────────────────┘└┘└───────────┘
doc  ─────┘                      └┘             
txt  ─────┘                      └┘             
par  ─────┘                      └┘             
pid  ─────┘                      └┘             
st   ───────────────────────────┘└─────────────┘└──
1439    rintro rfl, exact h rfl
id                        └─┘
src    └────────┘  └────┘ └─┘
typ    └────────┘  └────┘└─┘
doc    └────────┘  └────┘    
txt    └────────┘  └────┘    
par    └────────┘  └────┘    
pid          └──┘           
st   ───────────┘└────────────┘
1440  end
id   └─┘
typ  └─┘
st   └─┘
1441  
1442  namespace to_finsupp
1443  
1444  instance : is_add_monoid_hom (to_finsupp : multiset α → α →₀ ℕ) :=
id              └───────────────┘  └────────┘   └──────┘     └┘ 
src             └───────────────┘  └────────┘   └──────┘       └┘ 
typ             └───────────────┘  └────────┘   └──────┘     └┘ 
doc             └───────────────┘               └──────┘       └┘
1445  { map_zero := to_finsupp_zero,
id                 └─────────────┘
src                └─────────────┘
typ                └─────────────┘
1446    map_add  := to_finsupp_add }
id                 └────────────┘
src                └────────────┘
typ                └────────────┘
1447  
1448  end to_finsupp
1449  
1450  @[simp] lemma to_finsupp_to_multiset (s : multiset α) :
id                                             └──────┘ 
src                                            └──────┘
typ                                            └──────┘ 
doc    └──┘                                    └──────┘
1451    s.to_finsupp.to_multiset = s :=
id     └─────────┘└──────────┘  
src     └─────────┘└──────────┘ 
typ    └─────────┘└──────────┘  
1452  ext.2 $ λ a, by rw [finsupp.count_to_multiset, to_finsupp_apply]
id   └─┘               └───────────────────────┘  └──────────────┘
src  └─┘            └──┘└───────────────────────┘└┘└──────────────┘└─
typ  └─┘           └──┘└───────────────────────┘└┘└──────────────┘└─
doc                  └──┘                         └┘                └─
txt                  └──┘                         └┘                └─
par                  └──┘                         └┘                └─
pid                    └┘                         └┘                
st                  └────────────────────────────┘└────────────────┘
1453  
src  
typ  
doc  
txt  
par  
pid  
st   
1454  end multiset
1455  
1456  namespace finsupp
1457  variables {σ : Type*}
1458  
1459  instance [preorder α] [has_zero α] : preorder (σ →₀ α) :=
id             └──────┘    └──────┘     └──────┘   └┘ 
src            └──────┘     └──────┘      └──────┘    └┘
typ            └──────┘    └──────┘     └──────┘   └┘ 
doc                                                   └┘
1460  { le := λ f g, ∀ s, f s ≤ g s,
id                       
src                         
typ                      
1461    le_refl := λ f s, le_refl _,
id                     └─────┘
src                      └─────┘
typ                    └─────┘
1462    le_trans := λ f g h Hfg Hgh s, le_trans (Hfg s) (Hgh s) }
id                      └─┘ └─┘   └──────┘  └─┘    └─┘ 
src                                   └──────┘
typ                     └─┘ └─┘   └──────┘  └─┘    └─┘ 
1463  
1464  instance [partial_order α] [has_zero α] : partial_order (σ →₀ α) :=
id             └───────────┘    └──────┘     └───────────┘   └┘ 
src            └───────────┘     └──────┘      └───────────┘    └┘
typ            └───────────┘    └──────┘     └───────────┘   └┘ 
doc                                                             └┘
1465  { le_antisymm := λ f g hfg hgf, finsupp.ext $ λ s, le_antisymm (hfg s) (hgf s),
id                        └─┘ └─┘  └─────────┘       └─────────┘  └─┘    └─┘ 
src                                  └─────────┘        └─────────┘
typ                       └─┘ └─┘  └─────────┘       └─────────┘  └─┘    └─┘ 
1466    .. finsupp.preorder }
id        └──────────────┘
src       └──────────────┘
typ       └──────────────┘
1467  
1468  instance [ordered_cancel_comm_monoid α] :
id             └────────────────────────┘ 
src            └────────────────────────┘
typ            └────────────────────────┘ 
1469    add_left_cancel_semigroup (σ →₀ α) :=
id     └───────────────────────┘   └┘ 
src    └───────────────────────┘    └┘
typ    └───────────────────────┘   └┘ 
doc                                 └┘
1470  { add_left_cancel := λ a b c h, finsupp.ext $ λ s,
id                               └─────────┘     
src                                  └─────────┘
typ                              └─────────┘     
1471    by { rw finsupp.ext_iff at h, exact add_left_cancel (h s) },
id             └─────────────┘             └─────────────┘   
src         └─┘└─────────────┘└───┘  └────┘└─────────────┘   └┘
typ         └─┘└─────────────┘└───┘  └────┘└─────────────┘ └┘
doc         └─┘               └───┘  └────┘                  └┘
txt         └─┘               └───┘  └────┘                  └┘
par         └─┘               └───┘  └────┘                  └┘
pid                          └───┘                         
st       └────────────────────────┘└────────────────────────────┘└┘
1472    .. finsupp.add_monoid }
id        └────────────────┘
src       └────────────────┘
typ       └────────────────┘
1473  
1474  instance [ordered_cancel_comm_monoid α] :
id             └────────────────────────┘ 
src            └────────────────────────┘
typ            └────────────────────────┘ 
1475    add_right_cancel_semigroup (σ →₀ α) :=
id     └────────────────────────┘   └┘ 
src    └────────────────────────┘    └┘
typ    └────────────────────────┘   └┘ 
doc                                  └┘
1476  { add_right_cancel := λ a b c h, finsupp.ext $ λ s,
id                                └─────────┘     
src                                   └─────────┘
typ                               └─────────┘     
1477    by { rw finsupp.ext_iff at h, exact add_right_cancel (h s) },
id             └─────────────┘             └──────────────┘   
src         └─┘└─────────────┘└───┘  └────┘└──────────────┘   └┘
typ         └─┘└─────────────┘└───┘  └────┘└──────────────┘ └┘
doc         └─┘               └───┘  └────┘                   └┘
txt         └─┘               └───┘  └────┘                   └┘
par         └─┘               └───┘  └────┘                   └┘
pid                          └───┘                          
st       └────────────────────────┘└─────────────────────────────┘└┘
1478    .. finsupp.add_monoid }
id        └────────────────┘
src       └────────────────┘
typ       └────────────────┘
1479  
1480  instance [ordered_cancel_comm_monoid α] :
id             └────────────────────────┘ 
src            └────────────────────────┘
typ            └────────────────────────┘ 
1481    ordered_cancel_comm_monoid (σ →₀ α) :=
id     └────────────────────────┘   └┘ 
src    └────────────────────────┘    └┘
typ    └────────────────────────┘   └┘ 
doc                                  └┘
1482  { add_le_add_left := λ a b h c s, add_le_add_left (h s) (c s),
id                                └─────────────┘       
src                                    └─────────────┘
typ                               └─────────────┘       
1483    le_of_add_le_add_left := λ a b c h s, le_of_add_le_add_left (h s),
id                                      └───────────────────┘   
src                                          └───────────────────┘
typ                                     └───────────────────┘   
1484    .. finsupp.add_comm_monoid, .. finsupp.partial_order,
id        └─────────────────────┘     └───────────────────┘
src       └─────────────────────┘     └───────────────────┘
typ       └─────────────────────┘     └───────────────────┘
1485    .. finsupp.add_left_cancel_semigroup, .. finsupp.add_right_cancel_semigroup }
id        └───────────────────────────────┘     └────────────────────────────────┘
src       └───────────────────────────────┘     └────────────────────────────────┘
typ       └───────────────────────────────┘     └────────────────────────────────┘
1486  
1487  lemma le_iff [canonically_ordered_monoid α] (f g : σ →₀ α) :
id                 └────────────────────────┘           └┘ 
src                └────────────────────────┘             └┘
typ                └────────────────────────┘           └┘ 
doc                └────────────────────────┘             └┘
1488    f ≤ g ↔ ∀ s ∈ f.support, f s ≤ g s :=
id              └──────┘      
src                 └──────┘      
typ             └──────┘      
1489  ⟨λ h s hs, h s,
id        └┘   
typ       └┘   
1490  λ h s, if H : s ∈ f.support then h s H else (not_mem_support_iff.1 H).symm ▸ zero_le (g s)⟩
id        └┘       └──────┘               └─────────────────┘   └──┘   └─────┘   
src         └┘         └──────┘                  └─────────────────┘    └──┘   └─────┘
typ       └┘       └──────┘               └─────────────────┘   └──┘   └─────┘   
1491  
1492  @[simp] lemma add_eq_zero_iff [canonically_ordered_monoid α] (f g : σ →₀ α) :
id                                  └────────────────────────┘           └┘ 
src                                 └────────────────────────┘             └┘
typ                                 └────────────────────────┘           └┘ 
doc    └──┘                         └────────────────────────┘             └┘
1493    f + g = 0 ↔ f = 0 ∧ g = 0 :=
id                  
src                     
typ                 
1494  begin
st   └─────
1495    split,
src    └───┘
typ    └───┘
doc    └───┘
txt    └───┘
par    └───┘
st   ──────┘└─
1496    { assume h,
src      └──────┘
typ      └──────┘
doc      └──────┘
txt      └──────┘
par      └──────┘
pid      └──────┘
st   ───┘└──────┘└─
1497      split,
src      └───┘
typ      └───┘
doc      └───┘
txt      └───┘
par      └───┘
st   ────────┘└─
1498      all_goals
src      └─────────
typ      └─────────
doc      └─────────
txt      └─────────
par      └─────────
pid               
st   ──────────────
1499      { ext s,
src  ─────┘└───┘└─
typ  ─────┘└───┘└─
doc  ─────┘└───┘└─
txt  ─────┘└───┘└─
par  ─────┘└───┘└─
pid  ─────────────
st   ────┘└────┘└─
1500        suffices H : f s + g s = 0,
id                            
src  ─────┘└───────────┘    └┘└─
typ  ─────┘└───────────┘ └┘└─
doc  ─────┘└───────────┘      └┘└─
txt  ─────┘└───────────┘      └┘└─
par  ─────┘└───────────┘      └┘└─
pid  ──────────────────┘      └───
st   ───────────────────────────────┘└─
1501        { rw add_eq_zero_iff at H, cases H, assumption },
id              └─────────────┘             
src  ───────┘└─┘└─────────────┘└───┘└┘└────┘ └┘└─────────┘└──
typ  ───────┘└─┘└─────────────┘└───┘└┘└────┘└┘└─────────┘└──
doc  ───────┘└─┘               └───┘└┘└────┘ └┘└─────────┘└──
txt  ───────┘└─┘               └───┘└┘└────┘ └┘└─────────┘└──
par  ───────┘└─┘               └───┘└┘└────┘ └┘└─────────┘└──
pid  ──────────┘               └───────────┘ └───────────────
st   ──────┘└──────────────────────┘└───────┘└───────────┘└─
1502        show (f + g) s = 0,
id                    
src  ─────┘└───┘    └┘  └┘└─
typ  ─────┘└───┘  └┘ └┘└─
doc  ─────┘└───┘    └┘  └┘└─
txt  ─────┘└───┘    └┘  └┘└─
par  ─────┘└───┘    └┘  └┘└─
pid  ──────────┘    └┘  └───
st   ───────────────────────┘└─
1503        rw h, refl } },
id            
src  ─────┘└─┘ └┘└───┘└┘
typ  ─────┘└─┘└┘└───┘└┘
doc  ─────┘└─┘ └┘└───┘└┘
txt  ─────┘└─┘ └┘└───┘└┘
par  ─────┘└─┘ └┘└───┘└┘
pid  ────────┘ └──────┘
st   ─────────┘└─────┘└┘
1504    { rintro ⟨rfl, rfl⟩, simp }
src      └───────────────┘  └───┘
typ      └───────────────┘  └───┘
doc      └───────────────┘  └───┘
txt      └───────────────┘  └───┘
par      └───────────────┘  └───┘
pid            └─────────┘      
st   ────────────────────┘└─────┘└─
1505  end
st   ──┘
1506  
1507  attribute [simp] to_multiset_zero to_multiset_add
id                    └──────────────┘ └─────────────┘
src                   └──────────────┘ └─────────────┘
typ                   └──────────────┘ └─────────────┘
doc             └──┘
1508  
1509  @[simp] lemma to_multiset_to_finsupp (f : σ →₀ ℕ) :
id                                              └┘ 
src                                              └┘ 
typ                                             └┘ 
doc    └──┘                                      └┘
1510    f.to_multiset.to_finsupp = f :=
id     └──────────┘└─────────┘  
src     └──────────┘└─────────┘ 
typ    └──────────┘└─────────┘  
1511  ext $ λ s, by rw [multiset.to_finsupp_apply, count_to_multiset]
id   └─┘              └───────────────────────┘  └───────────────┘
src  └─┘           └──┘└───────────────────────┘└┘└───────────────┘└─
typ  └─┘          └──┘└───────────────────────┘└┘└───────────────┘└─
doc                └──┘                         └┘                 └─
txt                └──┘                         └┘                 └─
par                └──┘                         └┘                 └─
pid                  └┘                         └┘                 
st                └────────────────────────────┘└─────────────────┘
1512  
src  
typ  
doc  
txt  
par  
pid  
st   
1513  lemma to_multiset_strict_mono : strict_mono (@to_multiset σ) :=
id                                   └─────────┘   └─────────┘ 
src                                  └─────────┘   └─────────┘
typ                                  └─────────┘   └─────────┘ 
doc                                  └─────────┘
1514  λ m n h,
id       
typ      
1515  begin
st   └─────
1516    rw lt_iff_le_and_ne at h ⊢, cases h with h₁ h₂,
id        └──────────────┘               
src    └─┘└──────────────┘└─────┘  └────┘ └─────────┘
typ    └─┘└──────────────┘└─────┘  └────┘└─────────┘
doc    └─┘                └─────┘  └────┘ └─────────┘
txt    └─┘                └─────┘  └────┘ └─────────┘
par    └─┘                └─────┘  └────┘ └─────────┘
pid                      └─────┘        └─────────┘
st   ───────────────────────────┘└──────────────────┘└─
1517    split,
src    └───┘
typ    └───┘
doc    └───┘
txt    └───┘
par    └───┘
st   ──────┘└─
1518    { rw multiset.le_iff_count, intro s, erw [count_to_multiset m s, count_to_multiset], exact h₁ s },
id          └───────────────────┘                └───────────────┘    └───────────────┘         └┘ 
src      └─┘└───────────────────┘  └─────┘  └───┘└───────────────┘  └┘└───────────────┘  └────┘   
typ      └─┘└───────────────────┘  └─────┘  └───┘└───────────────┘└┘└───────────────┘  └────┘└┘
doc      └─┘                       └─────┘  └───┘                   └┘                   └────┘   
txt      └─┘                       └─────┘  └───┘                   └┘                   └────┘   
par      └─┘                       └─────┘  └───┘                   └┘                   └────┘   
pid                                    └┘     └┘                   └┘                           
st   ───┘└──────────────────────┘└───────┘└──────────────────────────┘└─────────────────┘└────────────┘└┘
1519    { intro H, apply h₂, replace H := congr_arg multiset.to_finsupp H, simpa using H }
id                                       └───────┘ └─────────────────┘               
src      └─────┘  └────┘    └───────────┘└───────┘└─────────────────┘   └──────────┘ 
typ      └─────┘  └────┘    └───────────┘└───────┘└─────────────────┘  └──────────┘
doc      └─────┘  └────┘    └───────────┘                               └──────────┘ 
txt      └─────┘  └────┘    └───────────┘                               └──────────┘ 
par      └─────┘  └────┘    └───────────┘                               └──────────┘ 
pid           └┘                  └┘└─┘                                    └────┘ 
st   ──────────┘└────────┘└────────────────────────────────────────────┘└──────────────┘└─
1520  end
st   ──┘
1521  
1522  lemma sum_id_lt_of_lt (m n : σ →₀ ℕ) (h : m < n) :
id                                 └┘          
src                                 └┘          
typ                                └┘          
doc                                 └┘
1523    m.sum (λ _, id) < n.sum (λ _, id) :=
id     └──┘      └┘   └──┘      └┘
src     └──┘       └┘    └──┘       └┘
typ    └──┘      └┘   └──┘      └┘
doc     └──┘              └──┘
1524  begin
st   └─────
1525    rw [← card_to_multiset, ← card_to_multiset],
id           └──────────────┘    └──────────────┘
src    └────┘└──────────────┘└──┘└──────────────┘
typ    └────┘└──────────────┘└──┘└──────────────┘
doc    └────┘                └──┘                
txt    └────┘                └──┘                
par    └────┘                └──┘                
pid      └──┘                └──┘                
st   ───────────────────────┘└──────────────────┘└──
1526    apply multiset.card_lt_of_lt,
id           └────────────────────┘
src    └────┘└────────────────────┘
typ    └────┘└────────────────────┘
doc    └────┘
txt    └────┘
par    └────┘
pid         
st   ─────────────────────────────┘└─
1527    exact to_multiset_strict_mono h
id           └─────────────────────┘ 
src    └────┘└─────────────────────┘ 
typ    └────┘└─────────────────────┘
doc    └────┘                        
txt    └────┘                        
par    └────┘                        
pid                                 
st   ─────────────────────────────────┘
1528  end
st   └─┘
1529  
1530  variable (σ)
1531  
1532  /-- The order on σ →₀ ℕ is well-founded.-/
1533  lemma lt_wf : well_founded (@has_lt.lt (σ →₀ ℕ) _) :=
id                 └──────────┘   └───────┘   └┘ 
src                └──────────┘   └───────┘    └┘ 
typ                └──────────┘   └───────┘   └┘ 
doc                                            └┘
1534  subrelation.wf (sum_id_lt_of_lt) $ inv_image.wf _ nat.lt_wf
id   └────────────┘  └─────────────┘    └──────────┘   └───────┘
src  └────────────┘  └─────────────┘    └──────────┘   └───────┘
typ  └────────────┘  └─────────────┘    └──────────┘   └───────┘
1535  
1536  instance decidable_le : decidable_rel (@has_le.le (σ →₀ ℕ) _) :=
id                           └───────────┘   └───────┘   └┘ 
src                          └───────────┘   └───────┘    └┘ 
typ                          └───────────┘   └───────┘   └┘ 
doc                                                       └┘
1537  λ m n, by rw le_iff; apply_instance
id              └────┘
src            └─┘└────┘  └──────────────
typ          └─┘└────┘  └──────────────
doc            └─┘        └──────────────
txt            └─┘        └──────────────
par            └─┘        └──────────────
pid                                    
st            └──────────────────────────
1538  
src  
typ  
doc  
txt  
par  
pid  
st   
1539  variable {σ}
1540  
1541  def antidiagonal (f : σ →₀ ℕ) : ((σ →₀ ℕ) × (σ →₀ ℕ)) →₀ ℕ :=
id                          └┘        └┘      └┘    └┘ 
src                          └┘         └┘       └┘    └┘ 
typ                         └┘        └┘      └┘    └┘ 
doc                          └┘          └┘         └┘     └┘
1542  (f.to_multiset.antidiagonal.map (prod.map multiset.to_finsupp multiset.to_finsupp)).to_finsupp
id    └──────────┘└───────────┘└──┘  └──────┘ └─────────────────┘ └─────────────────┘  └────────┘
src    └──────────┘└───────────┘└──┘  └──────┘ └─────────────────┘ └─────────────────┘  └────────┘
typ   └──────────┘└───────────┘└──┘  └──────┘ └─────────────────┘ └─────────────────┘  └────────┘
doc                └───────────┘└──┘
1543  
1544  lemma mem_antidiagonal_support {f : σ →₀ ℕ} {p : (σ →₀ ℕ) × (σ →₀ ℕ)} :
id                                        └┘          └┘      └┘ 
src                                        └┘           └┘       └┘ 
typ                                       └┘          └┘      └┘ 
doc                                        └┘            └┘         └┘
1545    p ∈ (antidiagonal f).support ↔ p.1 + p.2 = f :=
id        └──────────┘  └─────┘         
src        └──────────┘   └─────┘          
typ       └──────────┘  └─────┘         
1546  begin
st   └─────
1547    erw [multiset.mem_to_finset, multiset.mem_map],
id          └────────────────────┘  └──────────────┘
src    └───┘└────────────────────┘└┘└──────────────┘
typ    └───┘└────────────────────┘└┘└──────────────┘
doc    └───┘                      └┘                
txt    └───┘                      └┘                
par    └───┘                      └┘                
pid       └┘                      └┘                
st   ────────────────────────────┘└────────────────┘└──
1548    split,
src    └───┘
typ    └───┘
doc    └───┘
txt    └───┘
par    └───┘
st   ──────┘└─
1549    { rintros ⟨⟨a, b⟩, h, rfl⟩,
src      └──────────────────────┘
typ      └──────────────────────┘
doc      └──────────────────────┘
txt      └──────────────────────┘
par      └──────────────────────┘
pid             └───────────────┘
st   ───┘└──────────────────────┘└─
1550      rw multiset.mem_antidiagonal at h,
id          └───────────────────────┘
src      └─┘└───────────────────────┘└───┘
typ      └─┘└───────────────────────┘└───┘
doc      └─┘└───────────────────────┘└───┘
txt      └─┘                         └───┘
par      └─┘                         └───┘
pid                                 └───┘
st   ────────────────────────────────────┘└─
1551      simpa using congr_arg multiset.to_finsupp h },
id                   └───────┘ └─────────────────┘ 
src      └──────────┘└───────┘└─────────────────┘ 
typ      └──────────┘└───────┘└─────────────────┘
doc      └──────────┘                             
txt      └──────────┘                             
par      └──────────┘                             
pid           └────┘                             
st   ───────────────────────────────────────────────┘└┘
1552    { intro h,
src      └─────┘
typ      └─────┘
doc      └─────┘
txt      └─────┘
par      └─────┘
pid           └┘
st   ──────────┘└─
1553      refine ⟨⟨p.1.to_multiset, p.2.to_multiset⟩, _, _⟩,
id                                 
src      └─────┘   └──────────────┘ └────────────────────┘
typ      └─────┘   └──────────────┘└────────────────────┘
doc      └─────┘   └──────────────┘ └────────────────────┘
txt      └─────┘   └──────────────┘ └────────────────────┘
par      └─────┘   └──────────────┘ └────────────────────┘
pid               └──────────────┘ └────────────────────┘
st   ────────────────────────────────────────────────────┘└─
1554      { simpa using congr_arg to_multiset h },
id                     └───────┘ └─────────┘ 
src        └──────────┘└───────┘└─────────┘ 
typ        └──────────┘└───────┘└─────────┘
doc        └──────────┘                     
txt        └──────────┘                     
par        └──────────┘                     
pid             └────┘                     
st   ─────┘└──────────────────────────────────┘└┘
1555      { rw [prod.map, to_multiset_to_finsupp, to_multiset_to_finsupp, prod.mk.eta] } }
id             └──────┘  └────────────────────┘  └────────────────────┘  └─────────┘
src        └──┘└──────┘└┘└────────────────────┘└┘└────────────────────┘└┘└─────────┘└┘
typ        └──┘└──────┘└┘└────────────────────┘└┘└────────────────────┘└┘└─────────┘└┘
doc        └──┘        └┘                      └┘                      └┘           └┘
txt        └──┘        └┘                      └┘                      └┘           └┘
par        └──┘        └┘                      └┘                      └┘           └┘
pid          └┘        └┘                      └┘                      └┘           
st   ─────────────────┘└──────────────────────┘└──────────────────────┘└───────────┘└───
1556  end
st   ──┘
1557  
1558  @[simp] lemma antidiagonal_zero : antidiagonal (0 : σ →₀ ℕ) = single (0,0) 1 :=
id                                     └──────────┘       └┘    └────┘ 
src                                    └──────────┘        └┘    └────┘ 
typ                                    └──────────┘       └┘    └────┘ 
doc    └──┘                                                └┘      └────┘
1559  by rw [← multiset.to_finsupp_singleton]; refl
id            └───────────────────────────┘
src     └────┘└───────────────────────────┘  └────
typ     └────┘└───────────────────────────┘  └────
doc     └────┘                               └────
txt     └────┘                               └────
par     └────┘                               └────
pid       └──┘                                   
st     └──────────────────────────────────┘└──────
1560  
src  
typ  
doc  
txt  
par  
pid  
st   
1561  lemma swap_mem_antidiagonal_support {n : σ →₀ ℕ} {f} (hf : f ∈ (antidiagonal n).support) :
id                                             └┘                └──────────┘  └─────┘
src                                             └┘                 └──────────┘   └─────┘
typ                                            └┘                └──────────┘  └─────┘
doc                                             └┘
1562    f.swap ∈ (antidiagonal n).support :=
id     └───┘   └──────────┘  └─────┘
src     └───┘   └──────────┘   └─────┘
typ    └───┘   └──────────┘  └─────┘
doc     └───┘
1563  by simpa [mem_antidiagonal_support, add_comm] using hf
id             └──────────────────────┘  └──────┘        └┘
src     └─────┘└──────────────────────┘└┘└──────┘└──────┘  
typ     └─────┘└──────────────────────┘└┘└──────┘└──────┘└┘
doc     └─────┘                        └┘        └──────┘  
txt     └─────┘                        └┘        └──────┘  
par     └─────┘                        └┘        └──────┘  
pid                                  └┘        └────┘  
st     └────────────────────────────────────────────────────
1564  
src  
typ  
doc  
txt  
par  
pid  
st   
1565  end finsupp